Repository navigation
docs(r3): post-merge fix-forward — PB-4 §16 + PB-3 §9 Step 2 contradictions - #3138
Conversation
…ratification Director-tier L2.5 model for PB-2 tokenize per operator 2026-05-14 ratification (Decision 1.A scoping = Option A). PB-2 is the FURTHEST-ALONG pipeline stage — substrate authority already lives in `.dag`: - src/v3/std/tokenize.dag (Token + TokenKind taxonomy; LIVE 143 lines) - src/v3/compiler/tokenize.dag (tokenizer implementation; LIVE 154 lines) - src/v3/compiler/src/tokenize_generated.rs (AUTO-GENERATED; 362 lines) This is the END STATE that all other pipeline-stage migrations target. PB-2 L2.5 is correspondingly lighter — mostly verification + residual hand-Rust retirement, NOT new substrate authoring. Distinct §9 4-step framing: - Step 3 = VERIFY substrate completeness (audit per feedback_paper_shrink_variants) - Step 4 = HANDOFF/RETIRE residual hand-Rust scaffolding (coordinates with PB-Bootstrap-Process lane for codegen-driver retirement) Captures audit dimensions explicitly: - scanner-class definitions = declarative byte-pattern membership - recognition tables = closed-axis enums - state machine = structural transitions - no V2 `pub mod tokenize` absorption check §12 Q1: codegen-driver retirement scope — Director-recommend PB-Bootstrap-Process handles all codegen-driver retirement cross-cuttingly (not per-stage paper-shrink risk). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…-pure-bootstrap-zero.md Per cursor PR #3085 finding: §12.6 explicitly tables only 4 pipeline-stage migrations (emit→lower→infer→parse); tokenize is per design-pure-bootstrap-zero.md PB-2 lane. Same fix as PR #3085 commit 89fbd7a applied here. INVARIANTS P1 — documentation must not overstate authority cites. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…-2 live state honesty Same class as codex INLINE BLOCKING #3126 finding 1 (live state honesty for diagnostic coupling) applied preemptively to PB-2 tokenize L2.5. PB-2 §4.3 had "diagnostics coupled INTO List<Token>" framing which would overstate the live carrier shape (bare List<Token> has no diagnostic field; tokenize_generated.rs:96 today returns Result<Vec<Token>, Diagnostic>). Fix: §4.3 reframed with PROPOSED substrate extension explicit — new `TokenizedSource { tokens, diagnostics }` wrapper carrier as the typed-state output. Step 2 brief includes wrapper authoring in pipeline-slot PR scope. Same discipline as PR #3126 commit bdff8c5. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…trap.md not -zero.md) Per cursor APPROVE_WITH_COMMENTS /api/reviews/12087: PB-2 lane is defined in docs/design-pure-bootstrap.md §"PB-2 — tokenize retire" (line ~134), NOT docs/design-pure-bootstrap-zero.md. The -zero.md doc has Subsumed-lanes list with PB-1/PB-4/PB-5/PB-6 but NOT PB-2. Propagated fix applies same cite-error correction as PR #3066 §1.8 discipline: cite the actual doc, not an adjacent doc with similar name. INVARIANTS P2 single-authority-citation. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Cursor APPROVE_WITH_COMMENTS (/api/reviews/12093) caught two substantive contradictions I introduced when adding TokenizedSource in commit 2b9756b: 1. §4.3 vs §9 Step 2 signature mismatch — §4.3 said `-> TokenizedSource` but §9 Step 2 row still said `-> List<Token>`. Same `feedback_discipline_change_audit_all_contract_mentions` issue that's recurred 4x this session. 2. §4.3 referenced "§12 Q-new" but §12 only had Q1-Q5; broken anchor. Fix: 1. §9 Step 2 row updated: signature `-> TokenizedSource` with wrapper carrier shape `{ tokens, diagnostics }` per §4.3 2. §4.3 anchor updated: "§12 Q6" (resolved) 3. Added §12 Q6: TokenizedSource carrier shape ratification — (a) wrapper record vs (b) per-Token diagnostic coupling; Director-recommend (a) for PB-3 SurfaceModule parallelism 4. §14 + §15 + §16 Q-list refs updated to Q1-Q6 Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Codex REQUEST_CHANGES (sha b881de2) with 2 substantive findings: 1. §4.1 Token shape claim "optional lexeme: String" — wrong per live substrate at src/v3/std/tokenize.dag:65-67. Live Token has 2 fields only (kind + span); lexeme-content lives ON the TokenKind variants (Ident(String) / IntLit(String) / etc.). Fix: corrected §4.1 to reflect live carrier shape; payloads on TokenKind variants noted explicitly. 2. §12 Q4 substrate-completeness audit scoped only to tokenize_generated.rs — missed the regen_tokenize codegen- driver boundary. If regen_tokenize carries scanner-logic decisions (rather than mechanical template-rendering of substrate facts), the substrate isn't complete — the driver IS hand-Rust scanner logic in disguise. Fix: Q4 audit extended with (d) regen_tokenize codegen- driver logic audit + (e) ROADMAP.md deferral row option per feedback_paper_shrink_variants P5 receipt discipline. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
… scaffold disclosure Codex REQUEST_CHANGES (sha b881de2, full body) caught 2 substantive overstatements: 1. §2 line 46 claimed "tokenize failures produce typed TokenizeDiagnostic variants" — but live tokenize_generated.rs:96 returns generic `Result<Vec<Token>, Diagnostic>` with `Diagnostic::TokenizerError { message, span, correction }`. Typed TokenizeDiagnostic is a PROPOSED extension, not live state. Fix: §2 reframed with live state explicit + TokenizeDiagnostic marked PROPOSED per PR #3077 §12 Q7 ratification path. 2. §1 line 22 + §6 + §9 Step 2 line 198 framed PB-2 as "mostly verification" — but live tokenize.dag:16-30+ has TWO explicit tracked scaffold zones: - SG-1a: regen_tokenize parses raw source text for dag_keyword_set / dag_operators (ValueBody::Unparsed) - Character-level under-consumption: StringEscapeSpec / LocalPunctSpec.pattern / string_literal_delimiter as opaque Strings; hidden Rust character predicates (byte.is_ascii_digit etc.) at tokenize_generated.rs:15-22 leaking through codegen Residual hand-Rust is NOT just the codegen artifact — it includes (a) regen_tokenize logic, (b) SG-1a raw-text-extractor scaffold, (c) character-predicate scaffold leaking through codegen. Fix: §1 + §6 + §9 Step 2 reframed honestly. PB-2 is "FURTHER ALONG but not complete"; Step 4 carries scaffold-retirement scope, not just codegen-artifact retirement. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…ector-pb2-tokenize-l25-model
…tions Two post-merge doc-internal contradictions caught by reviewers after operator merged PR #3077 / #3126 / #3085 at 2026-05-15T00:21Z. **PR #3077 PB-4 lower §16 fix**: §16 "Memory disciplines applied" bullet said "diagnostics coupled INTO PreInferDag via biconditional" — but §4.3 (per openai-pro DiagnosticAnchor fix commit b812db9) constrains biconditional to PortAnchor-only. Other anchor kinds (DeclarationAnchor / RecordFieldAnchor / SurfaceFormAnchor) couple without port-state. Fix: §16 bullet honors §4.3 anchor-typed framing. **PR #3126 PB-3 parse §9 Step 2 fix**: §9 Step 2 row described diagnostics as "coupled INTO SurfaceModule" as if live — §4.3 correctly marks it PROPOSED. Same feedback_discipline_change_audit_all_contract_mentions pattern that's recurred this session. Fix: §9 Step 2 row clarified — "PROPOSED extension per §4.3"; Step 2 PR scope includes authoring the diagnostics field extension, NOT a live coupling. Per feedback_discipline_change_audit_all_contract_mentions: when a substantive fix changes a discipline framing, audit ALL sections (framing + contract + handoff). Post-merge audit surfaced these residual contradictions. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…ec parallel-authority + fail-closed weakening) Codex REQUEST_CHANGES on already-merged PR #3126 (/api/reviews/12175): 2 substantive findings on the post-merge doc. **Finding 1 (P2 violation — GrammarSpec parallel authority)**: §3.2 says GrammarSpec is compile-time-only, NOT runtime- interpreted (per Decision 3.B (b) operator override). But the proposed stage contract still took `grammar: GrammarSpec` as runtime input. Creates two authorities (compiled parser tables + runtime GrammarSpec value). Fix: §4.3 signature reframed to `fn parse(tokens: List<Token>) -> Result<SurfaceModule, ParseDiagnostic>` — NO runtime GrammarSpec input. Compile-time generated parser tables consumed via internal dispatch. Step 2 + Step 4 rows updated. **Finding 2 (P3 + Practices 1/2 — fail-closed weakening)**: Live parser at parse_generated.rs:138 returns `Result<SurfaceModule, Diagnostic>` (fail-closed; aborts on first error). Earlier draft proposed `SurfaceModule` with embedded diagnostics — would let partial-parse states be constructible + let downstream observe "success" output after parse failure. Violation of fail-closed discipline. Fix: signature preserves Result-sum (matches live + emit's pattern). Distinguished cross-stage: - Result-sum (parse + emit): fail-fast output domain - Typed-state-with-coupled-diagnostics (lower + infer): structural output domain where partial-failure IS valid intermediate Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…16 fail-closed honesty Cursor caught 2 more post-merge contradictions on PR #3126: 1. §4.1 line 81 "construction-time invariant" talks about "ParseDiagnostic in the diagnostic stream" tied to SurfaceModule path — but §5.2 + live parse_generated.rs:138 use Result<SurfaceModule, Diagnostic>. §4.1 reads as claim about today's plumbing. Fix: §4.1 reframed — live boundary explicit (Result-sum); construction-time invariant scoped to Ok-arm SurfaceModule + Err-arm ParseDiagnostic, no partial-parse with embedded diagnostics. 2. §16 line 397 cites C-8 as "ParseDiagnostic coupled INTO SurfaceModule" without qualifier — but §4.3 (post codex REQUEST_CHANGES fix) constrains to Result-sum. Fix: §16 bullet honors §4.3 Result-sum framing; cross-stage discriminator named. Same recurring feedback_discipline_change_audit_all_contract_mentions pattern — substantive fix to §4.3 + §9 Step 2 left §4.1 + §16 inconsistent. Post-merge audit catches. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
briansrls
left a comment
There was a problem hiding this comment.
Review metadata
- Provider / model:
codex/unknown - Commit:
f08b9525· Trigger:schedule - Thinking:
216s wall
BLOCKING (2)
Root Cause
docs/design-tokenize-stage-l25-model.mddiagnostic carrier draft copied the generated Rust scanner enum name instead of binding to the live.dagcharacter-class authority → useCharClass/a declared substrate ref and cite the owning.dagdeclaration.docs/design-tokenize-stage-l25-model.mdTokenizedSource was introduced locally but not reconciled with the pipeline boundary/parse input contract → specify whether parse consumesTokenizedSource.tokenswhile diagnostics remain on a retained stage carrier, or change the downstream signature/carrier flow explicitly.
| ``` | ||
| // Typed reference carriers (cross-stage discipline per openai-pro | ||
| // PR #3077 BLOCKING + INVARIANTS P2/P3): | ||
| type ScannerClassRef = ScannerCharClass // closed-axis sum from tokenize.dag |
This comment was marked as resolved.
This comment was marked as resolved.
Sorry, something went wrong.
|
|
||
| ### §7.3 Sibling-stage coordination | ||
|
|
||
| Cross-stage discipline: **tokenize** → List<Token> → parse → SurfaceModule → lower → PreInferDag → infer → InferredDag → emit → EmissionResult. |
This comment was marked as resolved.
This comment was marked as resolved.
Sorry, something went wrong.
…stop-signal Cursor INLINE BLOCKING caught §3.2 line 66 "rules extend automatically" weakens substrate-extension stop-signal. Thesis discipline: a 7th TypeConnective variant requires explicit C1 audit + named infer-rule receipt. Fix: §3.2 reframed. New TypeConnective variants do NOT extend automatically; require explicit C1 substrate-extension audit + named infer-rule receipt for the new variant's structural inference behavior. Per-variant structural facts means new variants need new per-variant facts, NOT silent inheritance. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…stic Practice 4 classification Cursor INLINE BLOCKING /api/reviews/12218 (line:112): proposed substrate coproducts (AlgebraAxis + InferDiagnostic) lack 🟢/🟡/🔴 classification + ledger/trigger per modeling-discipline Practice 4 (Coproduct dissolution). Fix: added 🟡 SCAFFOLD classification + named dissolution trigger for both: AlgebraAxis 🟡 SCAFFOLD: - Trigger: Step 2 brief enumerates full algebra-axiom set against infer.rs check sites + verifies coverage parity with live verification.dag:146 AlgebraicLawKind 3-variant subset → promote to 🟢 TERMINAL. InferDiagnostic 🟡 SCAFFOLD: - Trigger: Step 2 brief enumerates full variant set against parse_generated.rs / lower.rs / infer.rs diagnostic emission sites → promote to 🟢 TERMINAL. - Anti-bridge per Q6.5: does NOT collapse into CompilerDiagnosticKind without substrate-extension ratification per PR #3077 §12 Q7. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…on correction
Cursor INLINE BLOCKING /api/reviews/12251 line:130: §5.1 said
"every SurfaceItem variant maps 1:1 to a Declaration placeholder"
but live lower.rs:2950-2958 explicitly skips Let/Module/Import
in collect_symbols.
Verified via Read of lower.rs:2956-2958:
SurfaceItem::Let { .. } => continue,
SurfaceItem::Module { .. } => continue,
SurfaceItem::Import { .. } => continue,
Fix: §5.1 reframed — DeclarationAllocating variants (Fn /
FnExternalBody / Data / TypeAtom / TypeRecord) map to
placeholders; NonDeclarationAllocating variants (Let / Module /
Import) skip allocation per live lower.rs behavior.
Let-bodies lower to Bind expressions in Pass 2; Module/Import
are parsed-facts preserved but un-declared.
Earlier "every SurfaceItem variant" framing overstated; would
have steered Step 2/3 worker into wrong allocation contract.
Per INVARIANTS P1/P2 live-state honesty + facts-flow-forward.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…adened Cursor INLINE BLOCKING line:33: ElaborationSpec was defined only as Surface→Behavior recipe mapping, but lower constructs Declarations / TypeConnectives / BranchPatterns / Bindings as well. Non-Behavior lowering decisions outside declared authority violates THESIS substrate ownership + INVARIANTS P2. Fix: §3.2 ElaborationSpec scope broadened to ALL lowering decisions: 1. SurfaceItem → Declaration recipes (Fn / Data / Type variants + Let/Module/Import skip-allocation per §5.1) 2. SurfaceType → TypeConnective recipes (Atom / Arrow / Compose / Disj construction) 3. SurfaceExpr → Behavior recipes (Value / Transform / Branch / Loop / Bind construction) 4. SurfacePattern → BranchPattern recipes (ResolvedVariant / UnresolvedVariant / record-pattern construction) 5. Binding-site rules (Bind params + result_port construction) ElaborationSpec is single-authority across ALL axes; no axis lives in implementation-tier hand-Rust. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…dependence clarification Cursor APPROVE_WITH_COMMENTS /api/reviews/12265 line 197: §7.1 mixed two claims: - "parse migrates AFTER tokenize substrate-side stable" (ordering) - "PB-3 parse migration is independent of PB-2 tokenize migration status" (independence) Read as contradictory by reviewers. Need one coherent story. Fix: §7.1 reframed with two distinct axes explicit: 1. Substrate-stability ordering (SELF_HOSTING.md §2 bottom-up): tokenize Token carrier shape must be stable BEFORE parse migrates. Already true at HEAD (tokenize.dag:65-67 declares live carrier). ✓ 2. Migration-timing independence (parallel-dispatch axis): PB-3 parse migration ships in parallel with PB-2 residual-retirement work (SG-1a + character-level scaffold + codegen-driver retirement per PB-2 L2.5 §1). What parse needs is the stable Token CARRIER; PB-2's migration is about retiring residual hand-Rust, not changing the carrier. Both claims coherent on the axis split; not contradictory. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…n structural requirement Cursor INLINE BLOCKING /api/reviews/12277 line:65: ParseDiagnostic variants like UnexpectedToken lacked SourceSpan field; List<ParseDiagnostic> cannot satisfy fail-closed source attribution structurally without span on every variant. INVARIANTS P2/P3 violation. Fix: every ParseDiagnostic variant now carries SourceSpan structurally: - UnexpectedToken: added span: SourceSpan - UnterminatedConstruct: opener_span: SourceSpan (already present) - InvalidLiteral: added span: SourceSpan - DuplicateRecordFieldLabel: added span: SourceSpan (current site) + prior_span: SourceSpan (prior site; both required) Per INVARIANTS P2/P3 fail-closed source attribution discipline: every diagnostic emission carries structural source-span provenance; not optional. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…tom-reference fix Cursor INLINE BLOCKING /api/reviews/12279 line:29: §3.1 cited `src/v3/compiler/src/tokenize.rs` as "current hand-Rust" for Token carrier — but `tokenize.rs` (without _generated suffix) doesn't exist. Live state has tokenize.dag (live substrate) + tokenize_generated.rs (codegen artifact). Per design-pure-bootstrap.md PB-2 lane: tokenize retire has substantially landed. The reference was an earlier-draft phantom from when Token-was-hand-Rust framing was the assumption. Fix: §3.1 reframed — Token type lives in LIVE src/v3/std/tokenize.dag:65-67 shared taxonomy; tokenizer implementation also live at src/v3/compiler/tokenize.dag (154 lines); codegen artifact at tokenize_generated.rs. tokenize.rs phantom reference removed explicitly. PB-2 substantially landed per design-pure-bootstrap.md; residual scaffold-retirement scope per PB-2 L2.5 PR #3127. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…et fix (compiler.dag → pipeline.dag) Cursor INLINE BLOCKING /api/reviews/12281 line:138: §9 Step 2 referenced generic "compiler.dag" but dsl/gunbc/compiler.dag:24 explicitly directs internal pipeline (Tokenize → Parse → ...) to src/v3/compiler/pipeline.dag, NOT generic compiler.dag. Worker briefs authored against this doc would target the wrong file for pipeline-slot declaration. P2 single-authority violation. Fix: §9 Step 2 row in ALL 4 L2.5 docs (PB-2 / PB-3 / PB-4 / PB-5) updated: - "declared in compiler.dag" → "declared in src/v3/compiler/pipeline.dag (per dsl/gunbc/compiler.dag:24 — internal pipeline lives in pipeline.dag, NOT generic compiler.dag)" - substrate column: "compiler.dag refinement" → "pipeline.dag refinement" - §13 "Step 2 (pipeline-slot in compiler.dag)" → "pipeline-slot in src/v3/compiler/pipeline.dag" Same phantom-citation class as the tokenize.rs phantom (commit 8ae37b4): I cited generic file path without verifying which specific file is authoritative per project structure. Should have grep'd dsl/gunbc/compiler.dag header notes before authoring. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…ipt unambiguity
Cursor INLINE BLOCKING /api/reviews/12283 line:181: Q5 said
Step 3b "full parser body .dag migration + parser body deletion
in same PR", but §15 sequence schedules Step 4 parity/deletion
AFTER Step 3b merges. P5 dissolution receipt ambiguous.
If Step 3b lands .dag parser body BEFORE Step 4 deletes Rust
parse() body, Rust + .dag parser bodies coexist temporarily —
paper-shrink-relocation risk per feedback_paper_shrink_variants.
Fix:
1. §9 Step 3b row reframed as "Step 3b/4 COMBINED" — atomic
single PR (full .dag parser body + parity TestClaim +
parse_generated.rs:138 deletion + census shrink). Cannot land
.dag parser body before Rust deletion.
2. §12 Q5 phasing clarified:
- Phase 3a (separate PR): grammar table extension; P5 receipt
= ROADMAP deferral row naming Step 3b/4 as future-receipt
- Phase 3b/4 COMBINED (single PR): atomic substrate substitution
3. §9 + §15 update notes: sequence collapses steps 12-17 into
single dispatch+merge for combined phase
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Codex high-level BLOCKING (sha 140eb6b) had 4 findings: - Findings 3 + 4 already addressed in PR #3138 commits 0159773 + a1607a8 - Findings 1 + 2 addressed in this commit **Finding 1 (Diagnostic kind/record conflated)**: §4.2 ParseDiagnostic was modeled as variants-directly with span + kind-fields mixed. Live Diagnostic at diagnostics.dag:150 uses record-wraps-kind pattern (`{ kind, span, message, correction }`). Need consistent shape. Fix: refactored to record-wraps-kind: - `type ParseDiagnostic { kind: ParseDiagnosticKind, span: SourceSpan }` - `type ParseDiagnosticKind = UnexpectedToken | UnterminatedConstruct | InvalidLiteral | DuplicateRecordFieldLabel | ...` Span lives on ParseDiagnostic record (single source of truth); variant-specific spans (opener_span / prior_span) remain on kind variants where meaningful. **Finding 2 (PB-2 §6 obsolete sibling-lane assumption)**: §6 line 198 said "PB-2 Tokenize | src/v3/std/tokenize.dag (NEW per PB-2 L2.5)" — but tokenize.dag is ALREADY LIVE per design-pure-bootstrap.md §"PB-2 — tokenize retire" (substantially landed). Fix: §6 prereq table row updated to reflect LIVE state. PB-2's residual scope is scaffold-retirement (SG-1a + character-level + codegen-driver per PB-2 L2.5 §1), not carrier authoring. PB-3 consumes the live Token carrier; carrier shape stable across PB-2 residual-retirement timing. Findings 3 + 4 already addressed: - Finding 3 (pipeline.dag target): commit 0159773 - Finding 4 (Step 3b/4 atomic vs sequential): commit a1607a8 Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…el metadata" removed
Cursor APPROVE_WITH_COMMENTS line:79: §4.1 said "SurfaceModule
(verified live) carries List<SurfaceItem> + module-level
metadata" — but live parse_surface.dag:29 has ONLY
`{ items: List<SurfaceItem> }`. No metadata fields.
Phantom addition violated INVARIANTS P1 live-state honesty.
Fix: §4.1 reframed to match live carrier exactly. Same
phantom-addition class as tokenize.rs phantom (commit 8ae37b4).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…-variant + diagnostic-table PROPOSED Codex high-level BLOCKING (sha bf4d315) — 2 substantive findings: **Finding 1 (AtomPayload stale)**: §2 + §5 cited infer.rs:10 top-comment "Atom(Identifier { name, resolved })" — but live substrate.dag:87 has 5-variant AtomPayload sum: Literal | UnresolvedIdentifier | ResolvedByStructure | ResolvedByName | TypeParam. infer.rs top-comment is STALE vs live substrate. My doc inherited the drift. Fix: §2 enumeration corrected to all 5 AtomPayload variants per live substrate.dag:87. **Finding 2 (diagnostic-table PROPOSED, not live)**: §2 + §4.1 + §4.3 said "diagnostics.contains(port_id) biconditional" as if live — but Dag at substrate.dag:525 has ONLY { declarations, nodes, ports, clusters }. NO diagnostics field. Diagnostic-table is PROPOSED substrate extension. Fix: §2 fail-closed note flagged PROPOSED — Step 2 PR scope includes `diagnostics: Map<PortId, Diagnostic>` field extension to Dag, OR PB-Substrate prereq adds it before PB-5 dispatch. Same recurring feedback_grep_carrier_field_before_coupling_claim discipline (PR #3126 SurfaceModule analogous case); needed to grep type Dag fields BEFORE claiming the diagnostics field exists. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…SED diagnostic-table marking
Cursor INLINE BLOCKING line:94: §4.1 + §4.3 said "diagnostics
coupled INTO InferredDag" without flagging the diagnostic-table
as a substrate extension. Live Dag at substrate.dag:525 has
{ declarations, nodes, ports, clusters } — NO diagnostics field.
Earlier commit c0d96af added PROPOSED marking only in §2;
§4.1 + §4.3 needed same treatment.
Fix: §4.1 + §4.3 reframed with explicit PROPOSED substrate-
extension marking + reference to §2 for extension scope.
Construction-time invariant + structural coupling are both
contingent on the substrate-extension landing (Step 2 PR scope
or PB-Substrate prereq).
Same recurring feedback_grep_carrier_field_before_coupling_claim
discipline applied to §4.1 + §4.3 consistently with §2.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…ng resolved by PR #3077 merge Cursor inline BLOCKING at docs/design-parse-stage-l25-model.md:119 (sha at merge time of PR #3126) flagged a real internal contradiction: - §6 (lines 191, 207, 308) claimed "Step 2 (pipeline-slot declaration) is unblocked" - §7.2 (line 227) claimed "PR #3077 §12 Q7 must ratify before any Step 2 worker brief authoring" A worker reading the doc could land Step 2 (pipeline boundary) before the diagnostic carrier's P2/P3 failure shape was fixed. Resolution: PR #3077 (PB-4 lower L2.5) merged at 2026-05-15T00:21:19Z, carrying the §12 Q7 ratification of the Decision 2.B per-stage diagnostic extension path. The gate IS now satisfied at HEAD, so the resolution is fact-update (annotate Q7 as DONE with the merge timestamp) rather than retracting either §6 or §7.2. Edits: - §15 step 4: annotated "DONE 2026-05-15T00:21:19Z when PR #3077 merged" and added the explicit "Step 2 is now genuinely unblocked, not just procedurally next" framing so workers reading the sequence don't bypass the gate. - §7.2 line 227: rewritten from "Q7 must ratify before Step 2 brief authoring" (future tense, the contradiction surface) to "Gate satisfied 2026-05-15T00:21:19Z when PR #3077 merged; Step 2 worker brief authoring is unblocked at HEAD per §15 step 4." Cites the cursor finding as the resolution path. §6 unblocking statements stay as-is — they were correct at HEAD; the contradiction lived in §7.2's pre-merge framing. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…tep 2 unblocking claim Codex BLOCKING finding 2 (sha 16d21f4, 216s thinking): the Q7 dependency was recorded in §7.2/§15 but not in the other Step-2-unblocking sites at §6 lines 191, 207, 308 — risking a worker reading "Step 2 unblocked" without also reading the Q7 prerequisite. Codex framing: "make Q7 a hard precondition wherever Step 2 is called unblocked, or split Step 2 into pre-Q7 and post-Q7 scopes with separate receipts." Chose the first option since PR #3077 has already merged (2026-05-15T00:21:19Z) and splitting into pre/post-Q7 scopes is no longer load-bearing. Annotated all three §6 sites: - Line 191 (Implication for PB-3 migration): cites gate + merge timestamp + explicit "must NOT be brief-authored before that merge timestamp." - Line 207 (Critical observation): cites the Step 2 gate as PR #3077 §12 Q7 + merge timestamp + P3 failure-shape consequence if violated. - Line 308 (Director-recommend phase list): cites gate + §7.2/§15 step 4 cross-refs + merge timestamp. Codex BLOCKING finding 1 (GrammarSpec carrier non-existence) verified already resolved at HEAD via commit c97dc15 — every GrammarSpec mention now explicitly marks it as a concept-not-carrier; Step 2 signature is `fn parse(tokens: List<Token>) -> Result<SurfaceModule, ParseDiagnostic>` with no GrammarSpec parameter. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…icity + Q1 ratification-pending status openai-pro REQUEST_CHANGES on PR #3126 sha 16d21f4 flagged three findings. Findings 1 + 2 (signature vs realization mismatch under LAYER MODEL + P2/P3 boundary discipline) were already resolved at HEAD by earlier fix-forward commits — Step 2 signature is now `fn parse(tokens: List<Token>) -> Result<SurfaceModule, ParseDiagnostic>` matching live `parse_generated.rs:138` with no GrammarSpec parameter and no diagnostics-coupled SurfaceModule extension (§4.3 Result-sum disposition). Finding 6 (TRACKED vs UNTRACKED DEBT — Step 3b/4 same-PR vs two-PR): §9 had both a "Step 3b/4 COMBINED" row (line 250) and a leftover separate "Step 4: Parity test" row (line 251) — internally contradictory. §15 also still sequenced Steps 3b + 4 as four separate authoring/dispatch/ratify beats (steps 12-17), contradicting §12 Q5's "same PR" decision and the explicit "Update to §15" note at §12 line 325. Resolution: collapsed §9 to one COMBINED row absorbing the parity-TestClaim mechanics + P5 dissolution receipt from the deleted Step 4 row; collapsed §15 steps 12-17 into single COMBINED authoring + dispatch + ratify (steps 12-14). Added explicit `feedback_paper_shrink_variants` reasoning in both sections. Finding 2.5 (PM intent — substrate-capability bundled vs separate): §12 Q1 line 288 said "Director-recommend: (b) bundled" while §13 line 340 listed substrate-capability as a non-goal of PB-3 and §15 step 11 had "WAIT for substrate-capability landing" — three sections, two different execution paths. Resolution: annotated Q1 as "PENDING operator/PM ratification" with explicit default-execution clause: until operator ratifies, the doc treats substrate-capability as path (a) separate lane (matching §13 + §15 + §9 row). If/when ratified to (b), §13 drops the non-goal and §15 step 11 collapses into the COMBINED Step 3b/4 brief. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
… single enumerated authority Codex caught me copying the prose summary at parse_tables.dag:23-29 (which enumerates only SG-2c-numbered families) instead of grepping the live `^type [A-Z]` declarations. Result: SoftKeywordIdentRow (line 334) was missing from §3.2 / §5.1 / §6 / §12 because it lacks an SG-2c-N number in the prose summary. Per `feedback_parallel_representation_debt`: structural fix is to stop hand-enumerating in the doc — cite parse_tables.dag itself as the single enumerated authority and use `type`-declaration line-anchors for the worked example, not a hand-maintained count. Edits: - §3.2 §"Live substrate authority": replaced the SG-2c-numbered bullet list with `type`-declaration line-anchor enumeration including SoftKeywordIdentRow at parse_tables.dag:334 + the supporting enum BinaryOpLevel at line 133. Added codex-finding callout explaining the miss + the discipline shift. - §3 preamble line:33, §3.2 line:45 callout, §3.2 line:57 framing, §3.2 §"Substrate authority" line:71, §5.1 line:171-180, §12 Q2 line:298, §12 Q6 line:334: all hardcoded "6 table-families" counts dropped; doc now points readers to §3.2 enumeration / `parse_tables.dag` directly. - §5.1 sub-enumeration list (the parallel 6-item list at lines 173-178) deleted; replaced with redirect to §3.2 + restated 3a-vs-3b/4 scope split. Code-level check before commit: `grep -nE '^type [A-Z]' src/v3/compiler/parse_tables.dag` returns 7 types: BinaryOpLevel (133), BinaryOpRow (167), TopLevelItemKwRow (289), SoftKeywordIdentRow (334), BracketRow (385), PrimaryPrefixRow (449), PrimaryAtomRow (486). Doc enumeration matches. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…ource + cite concrete P5 receipts Codex review id 12370 on sha d15e1f2 raised two load-bearing planning-shape findings. Both addressed; this commit ports the same edits already living on fix-forward branch docs/director-l25-postmerge-cleanups (PR #3138 commit 6adb992) onto PR #3127's branch directly so codex BLOCKING resolves on this PR's own HEAD rather than waiting on PR #3138 merge. Finding 1 — parallel boundary carriers (INVARIANTS P2 / Practices 3+5): §4.3 + §9 Step 2 + §12 Q6 named `TokenizedSource { tokens, diagnostics }` as the output, while §2/§7.2/§7.3 named `List<Token>`. Same misclassification removed from the parse L2.5 (PR #3138 §4.3): tokenize sits in the fail-fast output domain alongside PB-3 parse + PB-6 emit (a partial token list with a corrupt token in the middle is not a valid downstream input for parse), so the failure couples via `Result`, not into the structural carrier. Resolution: - §4.3 rewritten to ratify `Result<List<Token>, TokenizeDiagnostic>` — the live `tokenize_generated.rs:96` shape — with no `TokenizedSource` extension. - §9 Step 2 row signature updated to match; explicit "single canonical boundary carrier: List<Token> on the Ok branch" framing. - §12 Q6 resolved REJECTED in-doc (no operator ratification needed; disposition follows from the cross-stage discriminator load-bearing in PR #3138 parse L2.5). - §16 memory-disciplines bullets rewritten parallel to PR #3138 parse §16: Result-sum, no diagnostics field on `List<Token>`. - §14 "Surfaces awaiting" trimmed Q6 from the operator-ratification list. Finding 2 — soft deferral of `regen_tokenize` retirement (INVARIANTS P5): deferral previously named "PB-Bootstrap-Process lane scope" without a concrete ROADMAP.md row. Updated §9 Step 2 + Step 4 rows to cite the named receipts: - `docs/design-pure-bootstrap-zero.md:116` (PB-Bootstrap-Process lane: author bootstrap.dag + generated trampoline; sized M). - `docs/design-pure-bootstrap-zero.md:118-123` (N=0 runtime verification gates). - ROADMAP.md:467 (Character-level under-consumption in tokenize + syntax authorities — phase-2 char-class retype owns the codegen-driver path). - ROADMAP.md:416 (Class 5 Gap 3 — top-level `ValueBody` boundary; gating substrate-capability for the phase-2 retype). - ROADMAP.md:53 (T-PB-A — non-test census → 0 floor). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…stic to live CharClass authority Codex Finding 1 (sha f08b952, 216s thinking): the §4.2 TokenizeDiagnostic draft and the §5.1/§5.2 headings used `ScannerCharClass` / `ScannerClassRef` — names that exist only as the *generated Rust enum spelling*, not as a declared .dag substrate type. Verified via grep: grep -rn '^type CharClass\|^type ScannerC' dsl/ src/v3/ returns ONE authority: `dsl/std/unicode.dag:62` type CharClass = Whitespace | Digit | IdentStart | IdentContinue consumed at `src/v3/compiler/tokenize.dag:103` data ascii_scan_order: List<CharClass> = [Whitespace, Digit, IdentStart, IdentContinue] There is no `ScannerCharClass` declaration anywhere — that name was copied from generated Rust without grep-verification, the same failure mode as `feedback_grep_substrate_before_naming_ratification` (carrier-name collision discipline). Resolution: - §4.2 TokenizeDiagnostic carrier: `expected_class: ScannerClassRef` → `expected_class: CharClass`, dropped the `type ScannerClassRef = ScannerCharClass` alias entirely; added a codex-finding callout citing the substrate authority + naming the failure mode. - §5.1 heading "Byte → ScannerCharClass dispatch" → "Byte → CharClass dispatch"; bullets unchanged; added line-anchor cites for the substrate authority + explicit "NOT ScannerCharClass" disclaimer. - §5.2 heading "ScannerCharClass → token-recognition state machine" → "CharClass → token-recognition state machine". Finding 2 (TokenizedSource not reconciled with parse input contract): no new fix required — already resolved by commit 6adb992 (TokenizedSource extension dropped entirely; tokenize uses Result<List<Token>, TokenizeDiagnostic>; List<Token> is the single canonical boundary carrier consumed by parse). Codex was reviewing sha f08b952, which predated the TokenizedSource drop. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…ive CharClass authority Porting the same fix that landed on PR #3138 commit 367fdc2 onto PR #3127's own branch so codex BLOCKING resolves on this PR's HEAD directly. Codex Finding 1: §4.2 TokenizeDiagnostic + §5.1/§5.2 headings used `ScannerCharClass` / `ScannerClassRef` — names that exist only in the generated Rust enum spelling, not as a .dag substrate declaration. Live authority is `dsl/std/unicode.dag:62` `type CharClass = Whitespace | Digit | IdentStart | IdentContinue`, consumed at `src/v3/compiler/tokenize.dag:103`. Resolution: - §4.2: `expected_class: ScannerClassRef` → `expected_class: CharClass`; dropped the `type ScannerClassRef = ScannerCharClass` alias; added codex-finding callout citing the substrate authority. - §5.1: heading + intro now cite `dsl/std/unicode.dag:62` directly. - §5.2: heading "CharClass → token-recognition state machine". Same failure-mode as `feedback_grep_substrate_before_naming_ratification`: naming a substrate carrier without grep-verifying against live .dag. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
Status reply for the cursor INLINE BLOCKING at docs/design-tokenize-stage-l25-model.md:96 (review at sha f08b952). Same root-cause as the codex BLOCKING I addressed in commit 367fdc2 on this PR's HEAD. At current HEAD:
The same fix was also ported to PR #3127's branch (sha 9ae4ef6) since it carries the same tokenize doc. — sent from zesty-bear-812 |
…in is Ok-branch propagation Cursor INLINE at sha f08b952 worried that §7.3's cross-stage chain "tokenize → List<Token> → parse → ..." was inconsistent with §4.3's TokenizedSource carrier (diagnostics not flowing forward). At HEAD the TokenizedSource extension is dropped (commit 6adb992); tokenize uses Result<List<Token>, TokenizeDiagnostic>, so List<Token> IS the canonical Ok-branch payload that flows forward and Err branches terminate the pipeline fail-fast. To make this explicit at §7.3 (instead of leaving readers to infer it from §4.3), annotated the chain with: - "Ok-branch propagation; Err branches are stage-terminal fail-fast per §4.3 Result-sum discriminator" framing prefix. - Per-stage Result/typed-state annotations: tokenize/parse show Result<Ok, Err>; lower/infer show typed-state structural-output; emit shows Result<EmittedArtifact, EmissionDiagnostic>. - Explicit "on any stage's Err branch the pipeline aborts at that stage (no partial-output propagation across boundaries)" trailer. This makes the chain self-consistent vis-a-vis §4.3 without requiring the reader to walk back-and-forth, and prevents future readers from re-introducing a TokenizedSource-shaped extension to "make diagnostics flow forward" — they already do, just via the Err branch terminating the pipeline. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…anch annotation Same edit as PR #3138 commit a8c0ff7 ported to this PR's branch. §7.3 cross-stage chain now annotates Ok-branch propagation + Err-branch fail-fast termination explicitly, eliminating the apparent contradiction between §4.3 (Result-sum) and §7.3 (List<Token> in the chain). They were already consistent — Ok-branch payload flows forward; Err terminates — but the annotation makes it self-evident at §7.3. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…l scaffold dissolution trigger openai-pro REQUEST_CHANGES on sha d15e1f2: §1 line:26 character-level under-consumption scaffold named the problem but lacked a checkable dissolution trigger. SG-1a scaffold above had the right shape — "once those bodies lower structurally under compile_to_dag, delete the raw-text extractor + derive directly from lowered Dag in same PR." Character-level scaffold just said "PB-2 Step 4 carries this scope" — a lane assignment, not a trigger. Resolution: rewrote §1 item 2 with the same SG-1a-shape trigger structure: - Substrate-consumption condition (a): scanner classes / string escape / local punctuation retype to `dsl/std/unicode.dag` `CharClass` / `char_in_class` (concrete field retypes named: `StringEscapeSpec.suffix: Char`, `LocalPunctSpec.pattern: List<Char>`, `string_literal_delimiter: Char`). - Codegen-driver condition (b): `tokenize_generated.rs` no longer emits hidden `byte.is_ascii_*` predicates because the driver reads class facts structurally from lowered `tokenize.dag`. - Same-PR dissolution: delete the parallel character-predicate scaffold in the same PR that flips substrate consumption — no Rust-and-`.dag` coexistence per `feedback_paper_shrink_variants`. - Cross-ref to §9 Step 4 gating prereqs: ROADMAP.md:467 + ROADMAP.md:416 Class 5 Gap 3 + std.unicode bootstrap/load-set decision (already cited in §9 from earlier commit 6adb992). Per openai-pro's framing: "small fix — mirror the SG-1a scaffold wording by naming the exact substrate-consumption condition and same-PR deletion receipt for the hidden Rust character predicates." Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…l scaffold dissolution trigger Same edit as PR #3138 commit 5a93d93 ported to this PR's branch. §1 item 2 character-level under-consumption scaffold now carries the same SG-1a-shape dissolution trigger structure: substrate-consumption condition (a) + codegen-driver condition (b) + same-PR delete receipt, with cross-refs to §9 Step 4 gating prereqs already cited. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
Status reply for codex review id 12391 on sha cd6e8d15c — both findings already resolved at HEAD (commit a76f421 on this branch, three pushes ago). Current state:
Both fixes landed in commit a76f421 in response to codex's earlier review on sha cd6e8d1 (same review content, surfaced twice). Subsequent commits 0d79c8e (Q7 hard precondition at every Step 2 unblocking site), 46e3004 (openai-pro Step 3b/4 atomicity + Q1 ratification status), 3eeee0c (parse_tables.dag single enumerated authority including SoftKeywordIdentRow), 367fdc2 / a8c0ff7 / 5a93d93 (tokenize-doc CharClass binding + §7.3 chain annotation + character-level dissolution trigger) all on top. PR HEAD is now 5a93d93. Dashboard please retally; cd6e8d15c is several pushes stale. — sent from zesty-bear-812 |
…y-rejected sweep Cursor review id 12405 (APPROVE_WITH_COMMENTS) caught the same `feedback_discipline_change_audit_all_contract_mentions` failure mode recurring: §12 Q6 was resolved REJECTED in commit 6adb992, and §14 "Surfaces awaiting" + §12 Q6 heading + §9 Step 2 row were updated, but two §-internal contract restatements were missed: - §14 acceptance criterion 11: "Operator/PM ratification on §12 Q1-Q6" - §15 step 1: "Operator / PM-delegate ratifies §12 Q1-Q6" Both contradicted §12 Q6 + §14 "Surfaces awaiting" (which already said "Q1-Q5 only"). A worker reading §14/§15 could schedule sign-offs on Q6 after it was already resolved-rejected elsewhere. Resolution: both sites now say "Q1–Q5" with the explicit Q6-rejected crossref + "see §14/§15 for same scoping" pointer at the §14 criterion so the three sections agree internally. Cursor verdict was APPROVE_WITH_COMMENTS (substantive APPROVE — "fix the checklist/sequence so every section agrees Q6 is closed"); the exploratory volatile-line-anchor note is harmless and out-of-scope for this PR. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…y-rejected sweep Same edit as PR #3138 commit 887c696 ported to this PR's branch. §14 acceptance criterion 11 + §15 step 1 now say "Q1-Q5" with explicit Q6-rejected crossrefs, aligning with §12 Q6 + §14 "Surfaces awaiting" which already said "Q1-Q5 only". Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…ratification (#3127) * docs(r3): PB-2 tokenize pipeline-stage L2.5 domain model — DRAFT for ratification Director-tier L2.5 model for PB-2 tokenize per operator 2026-05-14 ratification (Decision 1.A scoping = Option A). PB-2 is the FURTHEST-ALONG pipeline stage — substrate authority already lives in `.dag`: - src/v3/std/tokenize.dag (Token + TokenKind taxonomy; LIVE 143 lines) - src/v3/compiler/tokenize.dag (tokenizer implementation; LIVE 154 lines) - src/v3/compiler/src/tokenize_generated.rs (AUTO-GENERATED; 362 lines) This is the END STATE that all other pipeline-stage migrations target. PB-2 L2.5 is correspondingly lighter — mostly verification + residual hand-Rust retirement, NOT new substrate authoring. Distinct §9 4-step framing: - Step 3 = VERIFY substrate completeness (audit per feedback_paper_shrink_variants) - Step 4 = HANDOFF/RETIRE residual hand-Rust scaffolding (coordinates with PB-Bootstrap-Process lane for codegen-driver retirement) Captures audit dimensions explicitly: - scanner-class definitions = declarative byte-pattern membership - recognition tables = closed-axis enums - state machine = structural transitions - no V2 `pub mod tokenize` absorption check §12 Q1: codegen-driver retirement scope — Director-recommend PB-Bootstrap-Process handles all codegen-driver retirement cross-cuttingly (not per-stage paper-shrink risk). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * docs(r3): §12.6 citation fix — tokenize is PB-2 lane scope per design-pure-bootstrap-zero.md Per cursor PR #3085 finding: §12.6 explicitly tables only 4 pipeline-stage migrations (emit→lower→infer→parse); tokenize is per design-pure-bootstrap-zero.md PB-2 lane. Same fix as PR #3085 commit 89fbd7a applied here. INVARIANTS P1 — documentation must not overstate authority cites. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * docs(r3): preemptive fix for PR #3126 codex BLOCKING propagation — PB-2 live state honesty Same class as codex INLINE BLOCKING #3126 finding 1 (live state honesty for diagnostic coupling) applied preemptively to PB-2 tokenize L2.5. PB-2 §4.3 had "diagnostics coupled INTO List<Token>" framing which would overstate the live carrier shape (bare List<Token> has no diagnostic field; tokenize_generated.rs:96 today returns Result<Vec<Token>, Diagnostic>). Fix: §4.3 reframed with PROPOSED substrate extension explicit — new `TokenizedSource { tokens, diagnostics }` wrapper carrier as the typed-state output. Step 2 brief includes wrapper authoring in pipeline-slot PR scope. Same discipline as PR #3126 commit bdff8c5. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * docs(r3): cursor PR #3077 — fix PB-2 lane citation (design-pure-bootstrap.md not -zero.md) Per cursor APPROVE_WITH_COMMENTS /api/reviews/12087: PB-2 lane is defined in docs/design-pure-bootstrap.md §"PB-2 — tokenize retire" (line ~134), NOT docs/design-pure-bootstrap-zero.md. The -zero.md doc has Subsumed-lanes list with PB-1/PB-4/PB-5/PB-6 but NOT PB-2. Propagated fix applies same cite-error correction as PR #3066 §1.8 discipline: cite the actual doc, not an adjacent doc with similar name. INVARIANTS P2 single-authority-citation. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * docs(r3): fix cursor PR #3127 BLOCKING contradictions + add §12 Q6 Cursor APPROVE_WITH_COMMENTS (/api/reviews/12093) caught two substantive contradictions I introduced when adding TokenizedSource in commit 2b9756b: 1. §4.3 vs §9 Step 2 signature mismatch — §4.3 said `-> TokenizedSource` but §9 Step 2 row still said `-> List<Token>`. Same `feedback_discipline_change_audit_all_contract_mentions` issue that's recurred 4x this session. 2. §4.3 referenced "§12 Q-new" but §12 only had Q1-Q5; broken anchor. Fix: 1. §9 Step 2 row updated: signature `-> TokenizedSource` with wrapper carrier shape `{ tokens, diagnostics }` per §4.3 2. §4.3 anchor updated: "§12 Q6" (resolved) 3. Added §12 Q6: TokenizedSource carrier shape ratification — (a) wrapper record vs (b) per-Token diagnostic coupling; Director-recommend (a) for PB-3 SurfaceModule parallelism 4. §14 + §15 + §16 Q-list refs updated to Q1-Q6 Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * docs(r3): fix codex BLOCKING PR #3127 — Token shape + Q4 audit boundary Codex REQUEST_CHANGES (sha b881de2) with 2 substantive findings: 1. §4.1 Token shape claim "optional lexeme: String" — wrong per live substrate at src/v3/std/tokenize.dag:65-67. Live Token has 2 fields only (kind + span); lexeme-content lives ON the TokenKind variants (Ident(String) / IntLit(String) / etc.). Fix: corrected §4.1 to reflect live carrier shape; payloads on TokenKind variants noted explicitly. 2. §12 Q4 substrate-completeness audit scoped only to tokenize_generated.rs — missed the regen_tokenize codegen- driver boundary. If regen_tokenize carries scanner-logic decisions (rather than mechanical template-rendering of substrate facts), the substrate isn't complete — the driver IS hand-Rust scanner logic in disguise. Fix: Q4 audit extended with (d) regen_tokenize codegen- driver logic audit + (e) ROADMAP.md deferral row option per feedback_paper_shrink_variants P5 receipt discipline. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * docs(r3): fix codex BLOCKING PR #3127 — TokenizeDiagnostic PROPOSED + scaffold disclosure Codex REQUEST_CHANGES (sha b881de2, full body) caught 2 substantive overstatements: 1. §2 line 46 claimed "tokenize failures produce typed TokenizeDiagnostic variants" — but live tokenize_generated.rs:96 returns generic `Result<Vec<Token>, Diagnostic>` with `Diagnostic::TokenizerError { message, span, correction }`. Typed TokenizeDiagnostic is a PROPOSED extension, not live state. Fix: §2 reframed with live state explicit + TokenizeDiagnostic marked PROPOSED per PR #3077 §12 Q7 ratification path. 2. §1 line 22 + §6 + §9 Step 2 line 198 framed PB-2 as "mostly verification" — but live tokenize.dag:16-30+ has TWO explicit tracked scaffold zones: - SG-1a: regen_tokenize parses raw source text for dag_keyword_set / dag_operators (ValueBody::Unparsed) - Character-level under-consumption: StringEscapeSpec / LocalPunctSpec.pattern / string_literal_delimiter as opaque Strings; hidden Rust character predicates (byte.is_ascii_digit etc.) at tokenize_generated.rs:15-22 leaking through codegen Residual hand-Rust is NOT just the codegen artifact — it includes (a) regen_tokenize logic, (b) SG-1a raw-text-extractor scaffold, (c) character-predicate scaffold leaking through codegen. Fix: §1 + §6 + §9 Step 2 reframed honestly. PB-2 is "FURTHER ALONG but not complete"; Step 4 carries scaffold-retirement scope, not just codegen-artifact retirement. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * docs(r3): codex PR #3127 BLOCKING (review id 12370) — drop TokenizedSource + cite concrete P5 receipts Codex review id 12370 on sha d15e1f2 raised two load-bearing planning-shape findings. Both addressed; this commit ports the same edits already living on fix-forward branch docs/director-l25-postmerge-cleanups (PR #3138 commit 6adb992) onto PR #3127's branch directly so codex BLOCKING resolves on this PR's own HEAD rather than waiting on PR #3138 merge. Finding 1 — parallel boundary carriers (INVARIANTS P2 / Practices 3+5): §4.3 + §9 Step 2 + §12 Q6 named `TokenizedSource { tokens, diagnostics }` as the output, while §2/§7.2/§7.3 named `List<Token>`. Same misclassification removed from the parse L2.5 (PR #3138 §4.3): tokenize sits in the fail-fast output domain alongside PB-3 parse + PB-6 emit (a partial token list with a corrupt token in the middle is not a valid downstream input for parse), so the failure couples via `Result`, not into the structural carrier. Resolution: - §4.3 rewritten to ratify `Result<List<Token>, TokenizeDiagnostic>` — the live `tokenize_generated.rs:96` shape — with no `TokenizedSource` extension. - §9 Step 2 row signature updated to match; explicit "single canonical boundary carrier: List<Token> on the Ok branch" framing. - §12 Q6 resolved REJECTED in-doc (no operator ratification needed; disposition follows from the cross-stage discriminator load-bearing in PR #3138 parse L2.5). - §16 memory-disciplines bullets rewritten parallel to PR #3138 parse §16: Result-sum, no diagnostics field on `List<Token>`. - §14 "Surfaces awaiting" trimmed Q6 from the operator-ratification list. Finding 2 — soft deferral of `regen_tokenize` retirement (INVARIANTS P5): deferral previously named "PB-Bootstrap-Process lane scope" without a concrete ROADMAP.md row. Updated §9 Step 2 + Step 4 rows to cite the named receipts: - `docs/design-pure-bootstrap-zero.md:116` (PB-Bootstrap-Process lane: author bootstrap.dag + generated trampoline; sized M). - `docs/design-pure-bootstrap-zero.md:118-123` (N=0 runtime verification gates). - ROADMAP.md:467 (Character-level under-consumption in tokenize + syntax authorities — phase-2 char-class retype owns the codegen-driver path). - ROADMAP.md:416 (Class 5 Gap 3 — top-level `ValueBody` boundary; gating substrate-capability for the phase-2 retype). - ROADMAP.md:53 (T-PB-A — non-test census → 0 floor). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * docs(r3): codex PR #3138 BLOCKING (sha f08b952) Finding 1 — bind to live CharClass authority Porting the same fix that landed on PR #3138 commit 367fdc2 onto PR #3127's own branch so codex BLOCKING resolves on this PR's HEAD directly. Codex Finding 1: §4.2 TokenizeDiagnostic + §5.1/§5.2 headings used `ScannerCharClass` / `ScannerClassRef` — names that exist only in the generated Rust enum spelling, not as a .dag substrate declaration. Live authority is `dsl/std/unicode.dag:62` `type CharClass = Whitespace | Digit | IdentStart | IdentContinue`, consumed at `src/v3/compiler/tokenize.dag:103`. Resolution: - §4.2: `expected_class: ScannerClassRef` → `expected_class: CharClass`; dropped the `type ScannerClassRef = ScannerCharClass` alias; added codex-finding callout citing the substrate authority. - §5.1: heading + intro now cite `dsl/std/unicode.dag:62` directly. - §5.2: heading "CharClass → token-recognition state machine". Same failure-mode as `feedback_grep_substrate_before_naming_ratification`: naming a substrate carrier without grep-verifying against live .dag. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * docs(r3): cursor PR #3138 INLINE BLOCKING line:188 — §7.3 chain Ok-branch annotation Same edit as PR #3138 commit a8c0ff7 ported to this PR's branch. §7.3 cross-stage chain now annotates Ok-branch propagation + Err-branch fail-fast termination explicitly, eliminating the apparent contradiction between §4.3 (Result-sum) and §7.3 (List<Token> in the chain). They were already consistent — Ok-branch payload flows forward; Err terminates — but the annotation makes it self-evident at §7.3. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * docs(r3): openai-pro PR #3127 BLOCKING (sha d15e1f2) — character-level scaffold dissolution trigger Same edit as PR #3138 commit 5a93d93 ported to this PR's branch. §1 item 2 character-level under-consumption scaffold now carries the same SG-1a-shape dissolution trigger structure: substrate-consumption condition (a) + codegen-driver condition (b) + same-PR delete receipt, with cross-refs to §9 Step 4 gating prereqs already cited. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * docs(r3): cursor PR #3127 APPROVE_WITH_COMMENTS — §14 + §15 Q6-already-rejected sweep Same edit as PR #3138 commit 887c696 ported to this PR's branch. §14 acceptance criterion 11 + §15 step 1 now say "Q1-Q5" with explicit Q6-rejected crossrefs, aligning with §12 Q6 + §14 "Surfaces awaiting" which already said "Q1-Q5 only". Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
briansrls
left a comment
There was a problem hiding this comment.
Review metadata
- Provider / model:
codex/unknown - Commit:
887c6967· Trigger:schedule - Thinking:
333s wall
BLOCKING (5)
Root Cause
docs/design-infer-stage-l25-model.mdCross-stage Decision 2.B trigger prose was copied into the InferDiagnostic per-stage scaffold → make the trigger infer.rs-only and leave parse/lower coverage to their own per-stage carriers/Q7 mapping.docs/design-parse-stage-l25-model.mdResult-sum diagnostic refactor split record-vs-kind shape but omitted the coproduct receipt on the kind sums → mark ParseDiagnosticKind and TokenizeDiagnostic as 🟡 scaffold with the Step 2 full-site enumeration trigger or justify a 🟢 terminal ledger.docs/design-tokenize-stage-l25-model.mdPost-merge Q7 gate reconciliation was applied to the parse sequence but not to all downstream status/surfaces-awaiting sections → mark Q7 DONE consistently or remove it from awaiting gates.
| // substrate coproducts require 🟢/🟡/🔴 classification + dissolution trigger. | ||
| // | ||
| // **Dissolution trigger**: when Step 2 worker brief enumerates the full | ||
| // variant set against `parse_generated.rs` Diagnostic::ParseError, lower.rs |
There was a problem hiding this comment.
BLOCKING: InferDiagnostic's scaffold trigger requires enumerating parse and lower diagnostic sites for an infer-only sum, which violates P2 single-authority/layer discipline by making a per-stage carrier depend on sibling-stage authorities.
| // Optional: additional context fields per Step 2 brief enumeration | ||
| } | ||
|
|
||
| type ParseDiagnosticKind |
There was a problem hiding this comment.
BLOCKING: ParseDiagnosticKind is a proposed substrate coproduct with multiple variants but has no 🟢/🟡/🔴 Practice 4 classification or named dissolution trigger.
| // fixed in PR #3138). TokenizeDiagnostic references the live `CharClass` | ||
| // directly. | ||
|
|
||
| type TokenizeDiagnostic |
There was a problem hiding this comment.
BLOCKING: TokenizeDiagnostic is a proposed substrate coproduct with multiple variants but has no 🟢/🟡/🔴 Practice 4 classification or named dissolution trigger.
| 2. **PM amends close plan** to route through PB-X lanes + cite this doc as PB-3 L2.5 substrate | ||
| 3. **PM amends §1.8** with PB-3 gate row citing this doc | ||
| 4. **PR #3077 §12 Q7 ratifies** (cross-stage Decision 2.B extension path) — affects PB-3 ParseDiagnostic shape | ||
| 4. **PR #3077 §12 Q7 ratifies** (cross-stage Decision 2.B extension path) — affects PB-3 ParseDiagnostic shape. **DONE 2026-05-15T00:21:19Z** when PR #3077 (PB-4 lower L2.5) merged; Q7 ratification carried in that merge. The §6 / §7.2 "Step 2 must wait on Q7" gate is therefore now satisfied — Step 2 brief authoring is genuinely unblocked, not just procedurally listed as the next step. |
There was a problem hiding this comment.
BLOCKING: This line marks PR #3077 §12 Q7 DONE, but the same file still lists Q7 under §16 Surfaces awaiting, leaving the Step 2 gate internally contradictory.
|
|
||
| **Surfaces awaiting**: | ||
| - Operator/PM ratification on §12 Q1–Q5 (Q6 resolved REJECTED in-doc per codex PR #3127 BLOCKING — no ratification needed) | ||
| - PR #3077 §12 Q7 ratification (cross-stage Decision 2.B extension path) |
There was a problem hiding this comment.
BLOCKING: The new PB-2 doc still lists PR #3077 §12 Q7 ratification as awaiting even though the sibling PB-3 doc says that gate merged on 2026-05-15T00:21:19Z, so worker sequencing remains stale.
…ross 3 L2.5 docs Codex review id (sha 887c696, 333s thinking) flagged three findings, all `feedback_discipline_change_audit_all_contract_mentions` recurrences where partial sweeps left §-internal contradictions. Finding 1 — infer doc cross-stage trigger leak: §4.2 InferDiagnostic dissolution trigger said "when Step 2 worker brief enumerates the full variant set against `parse_generated.rs` Diagnostic::ParseError, lower.rs Diagnostic construction sites, and infer.rs Dag::mark_unresolved emission sites." That cross-stage trigger surface is wrong for the infer-specific scaffold. Narrowed to infer-only: "against `src/v3/compiler/src/infer.rs` Diagnostic construction sites + `Dag::mark_unresolved` emission sites (infer-stage only)." Parse and lower have their own per-stage carriers + own Q7 mapping; this doc no longer reaches into their dissolution-trigger surface. Finding 2 — parse + tokenize coproduct receipts: `ParseDiagnosticKind` (parse §4.2) and `TokenizeDiagnostic` (tokenize §4.2) sums were declared without the 🟡 SCAFFOLD / 🟢 TERMINAL classification + dissolution trigger that the infer doc carries (per modeling-discipline Practice 4 + `feedback_coproduct_dissolution`). Added matching scaffold receipts to both: 🟡 SCAFFOLD at PROPOSED stage with stage-local dissolution trigger (Step 2 brief enumerates against parse_generated.rs / tokenize_generated.rs Diagnostic::* construction sites — stage-only, not cross-stage); promote to 🟢 TERMINAL when full variant set lands. Both also carry the anti-bridge note per Q6.5. Finding 3 — tokenize Q7 reconciliation: The parse doc has the "Q7 DONE 2026-05-15T00:21:19Z" annotation at §15 step 4 (commit f85fa1f) but the tokenize doc still framed Q7 as a pending lane dependency at §4.2 line:113 ("Lane dependency"), §15 step 3, and §14 "Surfaces awaiting". Annotated all three: - §4.2 "Lane dependency": Q7 DONE timestamp + "TokenizeDiagnostic per-stage variant authoring is the remaining lane work." - §15 step 3: full DONE annotation matching parse doc §15 step 4 shape + cross-ref to the parse doc. - §14 "Surfaces awaiting": strikethrough + DONE annotation. PR #3127 also carries the tokenize doc; same edits will port there in a companion commit. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Same edits as PR #3138 commit e9739ea's tokenize-doc portion ported to this PR's branch. Finding 2 — TokenizeDiagnostic coproduct receipt: Added 🟡 SCAFFOLD classification + dissolution trigger (tokenize-stage only: Step 2 enumerates against tokenize_generated.rs:96 Diagnostic::* sites) + anti-bridge note per Q6.5. Finding 3 — Q7 reconciliation: §4.2 "Lane dependency", §15 step 3, and §14 "Surfaces awaiting" now all annotate Q7 as DONE 2026-05-15T00:21:19Z (PR #3077 merge timestamp); TokenizeDiagnostic per-stage variant authoring is the remaining lane work. (Finding 1 — infer-doc cross-stage trigger leak — does not apply to this branch; it lives on PR #3138's branch which carries the infer L2.5 doc.) Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
Status reply for the inline BLOCKING at docs/design-infer-stage-l25-model.md:150 (codex sha 887c696 Finding 1). Already addressed in commit e9739ea on this branch (3-finding sweep). Current state at HEAD: The §4.2 InferDiagnostic dissolution trigger no longer reaches into parse-stage or lower-stage diagnostic sites. The trigger is now infer-only:
Same commit also adds the missing 🟡 SCAFFOLD coproduct receipts to — sent from zesty-bear-812 |
|
Status reply for the inline BLOCKING at docs/design-parse-stage-l25-model.md:123 (codex sha 887c696 Finding 2 — same review I already responded to inline on infer.dag:150). Already addressed in commit e9739ea on this branch. At HEAD, ParseDiagnosticKind (and TokenizeDiagnostic per the same finding) now carry the 🟡 SCAFFOLD classification + dissolution trigger per modeling-discipline Practice 4 +
PR HEAD is now e9739ea. Dashboard appears to be caching the older 887c696 sha — git ls-remote confirms the push landed on origin. — sent from zesty-bear-812 |
|
Status reply for the inline BLOCKING at docs/design-tokenize-stage-l25-model.md:106 (codex sha 887c696 Finding 2, tokenize-doc side — same finding-class as the parse-doc inline at line 123 I responded to ~1 min ago). Already addressed in commit e9739ea on this branch (and ported to PR #3127 commit 10c89fd). At HEAD, TokenizeDiagnostic carries the matching 🟡 SCAFFOLD classification + dissolution trigger:
3 inlines from codex's sha 887c696 5-finding BLOCKING (infer.dag:150, parse.dag:123, tokenize.dag:106) all map to Findings 1 + 2 + 3 — all addressed at HEAD e9739ea / 10c89fd. — sent from zesty-bear-812 |
…iting Q7 contradiction Cursor inline at sha 887c696 caught the symmetric finding to the codex 5-finding BLOCKING #3: parse-doc §15 step 4 already annotated Q7 as DONE (commit f85fa1f) but parse-doc §16 "Surfaces awaiting" still listed Q7 as pending. Same `feedback_discipline_change_audit_all_contract_mentions` sweep failure — the tokenize doc had three sites carrying the pending framing (commit e9739ea fixed those) but the parse doc's §16 site was missed in the original Q7-DONE sweep. Resolution: §16 bullet now strikes through + "DONE 2026-05-15T00:21:19Z (PR #3077 merged carrying Q7 ratification; see §15 step 4)" — same shape as the tokenize doc's §14 "Surfaces awaiting" Q7-DONE annotation landed in e9739ea. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
Status reply for the inline BLOCKING at docs/design-tokenize-stage-l25-model.md:366 (cursor on sha 887c696 — same finding-class as the parse-doc §16 inline at line 372). Already addressed in commit e9739ea on this branch (and ported to PR #3127 commit 10c89fd). At HEAD, the "Surfaces awaiting" Q7 entry shifted to line 382 due to inserted scaffold-receipt content; the line reads:
§15 step 3 (line 340) also has the full DONE annotation matching the parse doc's §15 step 4 shape. §4.2 "Lane dependency" (line 129) likewise annotates Q7 as DONE. Three Q7-DONE sites on the tokenize doc now agree internally — matches the parse doc's three-site coverage (§7.2 + §15 step 4 + §16) post commit 4879685. No worker-sequencing staleness remains; the gate is satisfied by repo state. — sent from zesty-bear-812 |
…r inline Q7 sweep (#3140) * docs(r3): PB-2 tokenize pipeline-stage L2.5 domain model — DRAFT for ratification Director-tier L2.5 model for PB-2 tokenize per operator 2026-05-14 ratification (Decision 1.A scoping = Option A). PB-2 is the FURTHEST-ALONG pipeline stage — substrate authority already lives in `.dag`: - src/v3/std/tokenize.dag (Token + TokenKind taxonomy; LIVE 143 lines) - src/v3/compiler/tokenize.dag (tokenizer implementation; LIVE 154 lines) - src/v3/compiler/src/tokenize_generated.rs (AUTO-GENERATED; 362 lines) This is the END STATE that all other pipeline-stage migrations target. PB-2 L2.5 is correspondingly lighter — mostly verification + residual hand-Rust retirement, NOT new substrate authoring. Distinct §9 4-step framing: - Step 3 = VERIFY substrate completeness (audit per feedback_paper_shrink_variants) - Step 4 = HANDOFF/RETIRE residual hand-Rust scaffolding (coordinates with PB-Bootstrap-Process lane for codegen-driver retirement) Captures audit dimensions explicitly: - scanner-class definitions = declarative byte-pattern membership - recognition tables = closed-axis enums - state machine = structural transitions - no V2 `pub mod tokenize` absorption check §12 Q1: codegen-driver retirement scope — Director-recommend PB-Bootstrap-Process handles all codegen-driver retirement cross-cuttingly (not per-stage paper-shrink risk). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * docs(r3): §12.6 citation fix — tokenize is PB-2 lane scope per design-pure-bootstrap-zero.md Per cursor PR #3085 finding: §12.6 explicitly tables only 4 pipeline-stage migrations (emit→lower→infer→parse); tokenize is per design-pure-bootstrap-zero.md PB-2 lane. Same fix as PR #3085 commit 89fbd7a applied here. INVARIANTS P1 — documentation must not overstate authority cites. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * docs(r3): preemptive fix for PR #3126 codex BLOCKING propagation — PB-2 live state honesty Same class as codex INLINE BLOCKING #3126 finding 1 (live state honesty for diagnostic coupling) applied preemptively to PB-2 tokenize L2.5. PB-2 §4.3 had "diagnostics coupled INTO List<Token>" framing which would overstate the live carrier shape (bare List<Token> has no diagnostic field; tokenize_generated.rs:96 today returns Result<Vec<Token>, Diagnostic>). Fix: §4.3 reframed with PROPOSED substrate extension explicit — new `TokenizedSource { tokens, diagnostics }` wrapper carrier as the typed-state output. Step 2 brief includes wrapper authoring in pipeline-slot PR scope. Same discipline as PR #3126 commit bdff8c5. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * docs(r3): cursor PR #3077 — fix PB-2 lane citation (design-pure-bootstrap.md not -zero.md) Per cursor APPROVE_WITH_COMMENTS /api/reviews/12087: PB-2 lane is defined in docs/design-pure-bootstrap.md §"PB-2 — tokenize retire" (line ~134), NOT docs/design-pure-bootstrap-zero.md. The -zero.md doc has Subsumed-lanes list with PB-1/PB-4/PB-5/PB-6 but NOT PB-2. Propagated fix applies same cite-error correction as PR #3066 §1.8 discipline: cite the actual doc, not an adjacent doc with similar name. INVARIANTS P2 single-authority-citation. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * docs(r3): fix cursor PR #3127 BLOCKING contradictions + add §12 Q6 Cursor APPROVE_WITH_COMMENTS (/api/reviews/12093) caught two substantive contradictions I introduced when adding TokenizedSource in commit 2b9756b: 1. §4.3 vs §9 Step 2 signature mismatch — §4.3 said `-> TokenizedSource` but §9 Step 2 row still said `-> List<Token>`. Same `feedback_discipline_change_audit_all_contract_mentions` issue that's recurred 4x this session. 2. §4.3 referenced "§12 Q-new" but §12 only had Q1-Q5; broken anchor. Fix: 1. §9 Step 2 row updated: signature `-> TokenizedSource` with wrapper carrier shape `{ tokens, diagnostics }` per §4.3 2. §4.3 anchor updated: "§12 Q6" (resolved) 3. Added §12 Q6: TokenizedSource carrier shape ratification — (a) wrapper record vs (b) per-Token diagnostic coupling; Director-recommend (a) for PB-3 SurfaceModule parallelism 4. §14 + §15 + §16 Q-list refs updated to Q1-Q6 Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * docs(r3): fix codex BLOCKING PR #3127 — Token shape + Q4 audit boundary Codex REQUEST_CHANGES (sha b881de2) with 2 substantive findings: 1. §4.1 Token shape claim "optional lexeme: String" — wrong per live substrate at src/v3/std/tokenize.dag:65-67. Live Token has 2 fields only (kind + span); lexeme-content lives ON the TokenKind variants (Ident(String) / IntLit(String) / etc.). Fix: corrected §4.1 to reflect live carrier shape; payloads on TokenKind variants noted explicitly. 2. §12 Q4 substrate-completeness audit scoped only to tokenize_generated.rs — missed the regen_tokenize codegen- driver boundary. If regen_tokenize carries scanner-logic decisions (rather than mechanical template-rendering of substrate facts), the substrate isn't complete — the driver IS hand-Rust scanner logic in disguise. Fix: Q4 audit extended with (d) regen_tokenize codegen- driver logic audit + (e) ROADMAP.md deferral row option per feedback_paper_shrink_variants P5 receipt discipline. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * docs(r3): fix codex BLOCKING PR #3127 — TokenizeDiagnostic PROPOSED + scaffold disclosure Codex REQUEST_CHANGES (sha b881de2, full body) caught 2 substantive overstatements: 1. §2 line 46 claimed "tokenize failures produce typed TokenizeDiagnostic variants" — but live tokenize_generated.rs:96 returns generic `Result<Vec<Token>, Diagnostic>` with `Diagnostic::TokenizerError { message, span, correction }`. Typed TokenizeDiagnostic is a PROPOSED extension, not live state. Fix: §2 reframed with live state explicit + TokenizeDiagnostic marked PROPOSED per PR #3077 §12 Q7 ratification path. 2. §1 line 22 + §6 + §9 Step 2 line 198 framed PB-2 as "mostly verification" — but live tokenize.dag:16-30+ has TWO explicit tracked scaffold zones: - SG-1a: regen_tokenize parses raw source text for dag_keyword_set / dag_operators (ValueBody::Unparsed) - Character-level under-consumption: StringEscapeSpec / LocalPunctSpec.pattern / string_literal_delimiter as opaque Strings; hidden Rust character predicates (byte.is_ascii_digit etc.) at tokenize_generated.rs:15-22 leaking through codegen Residual hand-Rust is NOT just the codegen artifact — it includes (a) regen_tokenize logic, (b) SG-1a raw-text-extractor scaffold, (c) character-predicate scaffold leaking through codegen. Fix: §1 + §6 + §9 Step 2 reframed honestly. PB-2 is "FURTHER ALONG but not complete"; Step 4 carries scaffold-retirement scope, not just codegen-artifact retirement. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * docs(r3): post-merge fix-forward — §16 + §9 Step 2 internal contradictions Two post-merge doc-internal contradictions caught by reviewers after operator merged PR #3077 / #3126 / #3085 at 2026-05-15T00:21Z. **PR #3077 PB-4 lower §16 fix**: §16 "Memory disciplines applied" bullet said "diagnostics coupled INTO PreInferDag via biconditional" — but §4.3 (per openai-pro DiagnosticAnchor fix commit b812db9) constrains biconditional to PortAnchor-only. Other anchor kinds (DeclarationAnchor / RecordFieldAnchor / SurfaceFormAnchor) couple without port-state. Fix: §16 bullet honors §4.3 anchor-typed framing. **PR #3126 PB-3 parse §9 Step 2 fix**: §9 Step 2 row described diagnostics as "coupled INTO SurfaceModule" as if live — §4.3 correctly marks it PROPOSED. Same feedback_discipline_change_audit_all_contract_mentions pattern that's recurred this session. Fix: §9 Step 2 row clarified — "PROPOSED extension per §4.3"; Step 2 PR scope includes authoring the diagnostics field extension, NOT a live coupling. Per feedback_discipline_change_audit_all_contract_mentions: when a substantive fix changes a discipline framing, audit ALL sections (framing + contract + handoff). Post-merge audit surfaced these residual contradictions. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * docs(r3): post-merge fix-forward — PR #3126 codex BLOCKING (GrammarSpec parallel-authority + fail-closed weakening) Codex REQUEST_CHANGES on already-merged PR #3126 (/api/reviews/12175): 2 substantive findings on the post-merge doc. **Finding 1 (P2 violation — GrammarSpec parallel authority)**: §3.2 says GrammarSpec is compile-time-only, NOT runtime- interpreted (per Decision 3.B (b) operator override). But the proposed stage contract still took `grammar: GrammarSpec` as runtime input. Creates two authorities (compiled parser tables + runtime GrammarSpec value). Fix: §4.3 signature reframed to `fn parse(tokens: List<Token>) -> Result<SurfaceModule, ParseDiagnostic>` — NO runtime GrammarSpec input. Compile-time generated parser tables consumed via internal dispatch. Step 2 + Step 4 rows updated. **Finding 2 (P3 + Practices 1/2 — fail-closed weakening)**: Live parser at parse_generated.rs:138 returns `Result<SurfaceModule, Diagnostic>` (fail-closed; aborts on first error). Earlier draft proposed `SurfaceModule` with embedded diagnostics — would let partial-parse states be constructible + let downstream observe "success" output after parse failure. Violation of fail-closed discipline. Fix: signature preserves Result-sum (matches live + emit's pattern). Distinguished cross-stage: - Result-sum (parse + emit): fail-fast output domain - Typed-state-with-coupled-diagnostics (lower + infer): structural output domain where partial-failure IS valid intermediate Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * docs(r3): cursor PR #3126 post-merge APPROVE_WITH_COMMENTS — §4.1 + §16 fail-closed honesty Cursor caught 2 more post-merge contradictions on PR #3126: 1. §4.1 line 81 "construction-time invariant" talks about "ParseDiagnostic in the diagnostic stream" tied to SurfaceModule path — but §5.2 + live parse_generated.rs:138 use Result<SurfaceModule, Diagnostic>. §4.1 reads as claim about today's plumbing. Fix: §4.1 reframed — live boundary explicit (Result-sum); construction-time invariant scoped to Ok-arm SurfaceModule + Err-arm ParseDiagnostic, no partial-parse with embedded diagnostics. 2. §16 line 397 cites C-8 as "ParseDiagnostic coupled INTO SurfaceModule" without qualifier — but §4.3 (post codex REQUEST_CHANGES fix) constrains to Result-sum. Fix: §16 bullet honors §4.3 Result-sum framing; cross-stage discriminator named. Same recurring feedback_discipline_change_audit_all_contract_mentions pattern — substantive fix to §4.3 + §9 Step 2 left §4.1 + §16 inconsistent. Post-merge audit catches. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * docs(r3): cursor PR #3085 INLINE BLOCKING — TypeConnective extension stop-signal Cursor INLINE BLOCKING caught §3.2 line 66 "rules extend automatically" weakens substrate-extension stop-signal. Thesis discipline: a 7th TypeConnective variant requires explicit C1 audit + named infer-rule receipt. Fix: §3.2 reframed. New TypeConnective variants do NOT extend automatically; require explicit C1 substrate-extension audit + named infer-rule receipt for the new variant's structural inference behavior. Per-variant structural facts means new variants need new per-variant facts, NOT silent inheritance. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * docs(r3): cursor PR #3085 INLINE BLOCKING — AlgebraAxis + InferDiagnostic Practice 4 classification Cursor INLINE BLOCKING /api/reviews/12218 (line:112): proposed substrate coproducts (AlgebraAxis + InferDiagnostic) lack 🟢/🟡/🔴 classification + ledger/trigger per modeling-discipline Practice 4 (Coproduct dissolution). Fix: added 🟡 SCAFFOLD classification + named dissolution trigger for both: AlgebraAxis 🟡 SCAFFOLD: - Trigger: Step 2 brief enumerates full algebra-axiom set against infer.rs check sites + verifies coverage parity with live verification.dag:146 AlgebraicLawKind 3-variant subset → promote to 🟢 TERMINAL. InferDiagnostic 🟡 SCAFFOLD: - Trigger: Step 2 brief enumerates full variant set against parse_generated.rs / lower.rs / infer.rs diagnostic emission sites → promote to 🟢 TERMINAL. - Anti-bridge per Q6.5: does NOT collapse into CompilerDiagnosticKind without substrate-extension ratification per PR #3077 §12 Q7. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * docs(r3): cursor PR #3077 INLINE BLOCKING — §5.1 SurfaceItem allocation correction Cursor INLINE BLOCKING /api/reviews/12251 line:130: §5.1 said "every SurfaceItem variant maps 1:1 to a Declaration placeholder" but live lower.rs:2950-2958 explicitly skips Let/Module/Import in collect_symbols. Verified via Read of lower.rs:2956-2958: SurfaceItem::Let { .. } => continue, SurfaceItem::Module { .. } => continue, SurfaceItem::Import { .. } => continue, Fix: §5.1 reframed — DeclarationAllocating variants (Fn / FnExternalBody / Data / TypeAtom / TypeRecord) map to placeholders; NonDeclarationAllocating variants (Let / Module / Import) skip allocation per live lower.rs behavior. Let-bodies lower to Bind expressions in Pass 2; Module/Import are parsed-facts preserved but un-declared. Earlier "every SurfaceItem variant" framing overstated; would have steered Step 2/3 worker into wrong allocation contract. Per INVARIANTS P1/P2 live-state honesty + facts-flow-forward. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * docs(r3): cursor PR #3077 INLINE BLOCKING — ElaborationSpec scope broadened Cursor INLINE BLOCKING line:33: ElaborationSpec was defined only as Surface→Behavior recipe mapping, but lower constructs Declarations / TypeConnectives / BranchPatterns / Bindings as well. Non-Behavior lowering decisions outside declared authority violates THESIS substrate ownership + INVARIANTS P2. Fix: §3.2 ElaborationSpec scope broadened to ALL lowering decisions: 1. SurfaceItem → Declaration recipes (Fn / Data / Type variants + Let/Module/Import skip-allocation per §5.1) 2. SurfaceType → TypeConnective recipes (Atom / Arrow / Compose / Disj construction) 3. SurfaceExpr → Behavior recipes (Value / Transform / Branch / Loop / Bind construction) 4. SurfacePattern → BranchPattern recipes (ResolvedVariant / UnresolvedVariant / record-pattern construction) 5. Binding-site rules (Bind params + result_port construction) ElaborationSpec is single-authority across ALL axes; no axis lives in implementation-tier hand-Rust. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * docs(r3): cursor PR #3126 APPROVE_WITH_COMMENTS — §7.1 ordering vs independence clarification Cursor APPROVE_WITH_COMMENTS /api/reviews/12265 line 197: §7.1 mixed two claims: - "parse migrates AFTER tokenize substrate-side stable" (ordering) - "PB-3 parse migration is independent of PB-2 tokenize migration status" (independence) Read as contradictory by reviewers. Need one coherent story. Fix: §7.1 reframed with two distinct axes explicit: 1. Substrate-stability ordering (SELF_HOSTING.md §2 bottom-up): tokenize Token carrier shape must be stable BEFORE parse migrates. Already true at HEAD (tokenize.dag:65-67 declares live carrier). ✓ 2. Migration-timing independence (parallel-dispatch axis): PB-3 parse migration ships in parallel with PB-2 residual-retirement work (SG-1a + character-level scaffold + codegen-driver retirement per PB-2 L2.5 §1). What parse needs is the stable Token CARRIER; PB-2's migration is about retiring residual hand-Rust, not changing the carrier. Both claims coherent on the axis split; not contradictory. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * docs(r3): cursor PR #3126 INLINE BLOCKING — ParseDiagnostic SourceSpan structural requirement Cursor INLINE BLOCKING /api/reviews/12277 line:65: ParseDiagnostic variants like UnexpectedToken lacked SourceSpan field; List<ParseDiagnostic> cannot satisfy fail-closed source attribution structurally without span on every variant. INVARIANTS P2/P3 violation. Fix: every ParseDiagnostic variant now carries SourceSpan structurally: - UnexpectedToken: added span: SourceSpan - UnterminatedConstruct: opener_span: SourceSpan (already present) - InvalidLiteral: added span: SourceSpan - DuplicateRecordFieldLabel: added span: SourceSpan (current site) + prior_span: SourceSpan (prior site; both required) Per INVARIANTS P2/P3 fail-closed source attribution discipline: every diagnostic emission carries structural source-span provenance; not optional. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * docs(r3): cursor PR #3126 INLINE BLOCKING — Token authority cite phantom-reference fix Cursor INLINE BLOCKING /api/reviews/12279 line:29: §3.1 cited `src/v3/compiler/src/tokenize.rs` as "current hand-Rust" for Token carrier — but `tokenize.rs` (without _generated suffix) doesn't exist. Live state has tokenize.dag (live substrate) + tokenize_generated.rs (codegen artifact). Per design-pure-bootstrap.md PB-2 lane: tokenize retire has substantially landed. The reference was an earlier-draft phantom from when Token-was-hand-Rust framing was the assumption. Fix: §3.1 reframed — Token type lives in LIVE src/v3/std/tokenize.dag:65-67 shared taxonomy; tokenizer implementation also live at src/v3/compiler/tokenize.dag (154 lines); codegen artifact at tokenize_generated.rs. tokenize.rs phantom reference removed explicitly. PB-2 substantially landed per design-pure-bootstrap.md; residual scaffold-retirement scope per PB-2 L2.5 PR #3127. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * docs(r3): cursor PR #3126 INLINE BLOCKING — Step 2 pipeline-slot target fix (compiler.dag → pipeline.dag) Cursor INLINE BLOCKING /api/reviews/12281 line:138: §9 Step 2 referenced generic "compiler.dag" but dsl/gunbc/compiler.dag:24 explicitly directs internal pipeline (Tokenize → Parse → ...) to src/v3/compiler/pipeline.dag, NOT generic compiler.dag. Worker briefs authored against this doc would target the wrong file for pipeline-slot declaration. P2 single-authority violation. Fix: §9 Step 2 row in ALL 4 L2.5 docs (PB-2 / PB-3 / PB-4 / PB-5) updated: - "declared in compiler.dag" → "declared in src/v3/compiler/pipeline.dag (per dsl/gunbc/compiler.dag:24 — internal pipeline lives in pipeline.dag, NOT generic compiler.dag)" - substrate column: "compiler.dag refinement" → "pipeline.dag refinement" - §13 "Step 2 (pipeline-slot in compiler.dag)" → "pipeline-slot in src/v3/compiler/pipeline.dag" Same phantom-citation class as the tokenize.rs phantom (commit 8ae37b4): I cited generic file path without verifying which specific file is authoritative per project structure. Should have grep'd dsl/gunbc/compiler.dag header notes before authoring. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * docs(r3): cursor PR #3126 INLINE BLOCKING — Step 3b/4 phasing P5 receipt unambiguity Cursor INLINE BLOCKING /api/reviews/12283 line:181: Q5 said Step 3b "full parser body .dag migration + parser body deletion in same PR", but §15 sequence schedules Step 4 parity/deletion AFTER Step 3b merges. P5 dissolution receipt ambiguous. If Step 3b lands .dag parser body BEFORE Step 4 deletes Rust parse() body, Rust + .dag parser bodies coexist temporarily — paper-shrink-relocation risk per feedback_paper_shrink_variants. Fix: 1. §9 Step 3b row reframed as "Step 3b/4 COMBINED" — atomic single PR (full .dag parser body + parity TestClaim + parse_generated.rs:138 deletion + census shrink). Cannot land .dag parser body before Rust deletion. 2. §12 Q5 phasing clarified: - Phase 3a (separate PR): grammar table extension; P5 receipt = ROADMAP deferral row naming Step 3b/4 as future-receipt - Phase 3b/4 COMBINED (single PR): atomic substrate substitution 3. §9 + §15 update notes: sequence collapses steps 12-17 into single dispatch+merge for combined phase Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * docs(r3): codex PR #3126 high-level BLOCKING findings 1 + 2 Codex high-level BLOCKING (sha 140eb6b) had 4 findings: - Findings 3 + 4 already addressed in PR #3138 commits 0159773 + a1607a8 - Findings 1 + 2 addressed in this commit **Finding 1 (Diagnostic kind/record conflated)**: §4.2 ParseDiagnostic was modeled as variants-directly with span + kind-fields mixed. Live Diagnostic at diagnostics.dag:150 uses record-wraps-kind pattern (`{ kind, span, message, correction }`). Need consistent shape. Fix: refactored to record-wraps-kind: - `type ParseDiagnostic { kind: ParseDiagnosticKind, span: SourceSpan }` - `type ParseDiagnosticKind = UnexpectedToken | UnterminatedConstruct | InvalidLiteral | DuplicateRecordFieldLabel | ...` Span lives on ParseDiagnostic record (single source of truth); variant-specific spans (opener_span / prior_span) remain on kind variants where meaningful. **Finding 2 (PB-2 §6 obsolete sibling-lane assumption)**: §6 line 198 said "PB-2 Tokenize | src/v3/std/tokenize.dag (NEW per PB-2 L2.5)" — but tokenize.dag is ALREADY LIVE per design-pure-bootstrap.md §"PB-2 — tokenize retire" (substantially landed). Fix: §6 prereq table row updated to reflect LIVE state. PB-2's residual scope is scaffold-retirement (SG-1a + character-level + codegen-driver per PB-2 L2.5 §1), not carrier authoring. PB-3 consumes the live Token carrier; carrier shape stable across PB-2 residual-retirement timing. Findings 3 + 4 already addressed: - Finding 3 (pipeline.dag target): commit 0159773 - Finding 4 (Step 3b/4 atomic vs sequential): commit a1607a8 Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * docs(r3): cursor PR #3126 APPROVE_WITH_COMMENTS — phantom "module-level metadata" removed Cursor APPROVE_WITH_COMMENTS line:79: §4.1 said "SurfaceModule (verified live) carries List<SurfaceItem> + module-level metadata" — but live parse_surface.dag:29 has ONLY `{ items: List<SurfaceItem> }`. No metadata fields. Phantom addition violated INVARIANTS P1 live-state honesty. Fix: §4.1 reframed to match live carrier exactly. Same phantom-addition class as tokenize.rs phantom (commit 8ae37b4). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * docs(r3): codex PR #3085 high-level BLOCKING findings — AtomPayload 5-variant + diagnostic-table PROPOSED Codex high-level BLOCKING (sha bf4d315) — 2 substantive findings: **Finding 1 (AtomPayload stale)**: §2 + §5 cited infer.rs:10 top-comment "Atom(Identifier { name, resolved })" — but live substrate.dag:87 has 5-variant AtomPayload sum: Literal | UnresolvedIdentifier | ResolvedByStructure | ResolvedByName | TypeParam. infer.rs top-comment is STALE vs live substrate. My doc inherited the drift. Fix: §2 enumeration corrected to all 5 AtomPayload variants per live substrate.dag:87. **Finding 2 (diagnostic-table PROPOSED, not live)**: §2 + §4.1 + §4.3 said "diagnostics.contains(port_id) biconditional" as if live — but Dag at substrate.dag:525 has ONLY { declarations, nodes, ports, clusters }. NO diagnostics field. Diagnostic-table is PROPOSED substrate extension. Fix: §2 fail-closed note flagged PROPOSED — Step 2 PR scope includes `diagnostics: Map<PortId, Diagnostic>` field extension to Dag, OR PB-Substrate prereq adds it before PB-5 dispatch. Same recurring feedback_grep_carrier_field_before_coupling_claim discipline (PR #3126 SurfaceModule analogous case); needed to grep type Dag fields BEFORE claiming the diagnostics field exists. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * docs(r3): cursor PR #3085 INLINE BLOCKING line:94 — §4.1 + §4.3 PROPOSED diagnostic-table marking Cursor INLINE BLOCKING line:94: §4.1 + §4.3 said "diagnostics coupled INTO InferredDag" without flagging the diagnostic-table as a substrate extension. Live Dag at substrate.dag:525 has { declarations, nodes, ports, clusters } — NO diagnostics field. Earlier commit c0d96af added PROPOSED marking only in §2; §4.1 + §4.3 needed same treatment. Fix: §4.1 + §4.3 reframed with explicit PROPOSED substrate- extension marking + reference to §2 for extension scope. Construction-time invariant + structural coupling are both contingent on the substrate-extension landing (Step 2 PR scope or PB-Substrate prereq). Same recurring feedback_grep_carrier_field_before_coupling_claim discipline applied to §4.1 + §4.3 consistently with §2. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * docs(r3): codex PR #3077 high-level BLOCKING — Practice 4 classifications for PB-4 coproducts Codex high-level BLOCKING (sha b812db9): "Diagnostic substrate shape was repaired around anchoring but not re-audited as new substrate type declarations" — meaning DiagnosticAnchor + LowerDiagnostic + SurfaceFormRef + IdentifierRef need 🟢/🟡/🔴 classifications per modeling-discipline Practice 4 (Coproduct dissolution). Same pattern as PB-5 fix in commit 040681f (AlgebraAxis + InferDiagnostic) applied here. Fix: added classifications + dissolution triggers: - SurfaceFormRef 🟢 TERMINAL: closed-axis sum over live Surface* carriers; no further dissolution. - IdentifierRef 🟡 SCAFFOLD: dissolution trigger = Step 2 brief enumerates full identifier-kind set against lower.rs identifier-resolution sites; promote to 🟢 TERMINAL when SurfaceVarRef + TypePathRef + ModulePathRef cover actual axes. - LowerDiagnostic 🟡 SCAFFOLD: dissolution trigger = Step 2 brief enumerates variant set against lower.rs Diagnostic emission sites + Q6.5 anti-bridge preserved + PR #3077 §12 Q7 ratification path. - DiagnosticAnchor 🟢 TERMINAL: closed-axis covering all lowering-stage anchor kinds; no further dissolution. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * docs(r3): cursor PR #3077 INLINE BLOCKING line:161 — DiagnosticSource Practice 4 classification Cursor inline finding adds DiagnosticSource to Practice 4 classification scope. Earlier commit aba79a1 classified SurfaceFormRef + IdentifierRef + LowerDiagnostic + DiagnosticAnchor but missed DiagnosticSource. Fix: DiagnosticSource 🟢 TERMINAL at pipeline-stage discrimination scope. Closed-axis sum (Parse | Lower | Infer | Emit); adding new pipeline stage requires explicit substrate- extension audit per Practice 4 + stop-signal discipline (same shape as PB-5 §3.2 TypeConnective stop-signal). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * docs(r3): cursor PR #3126 INLINE BLOCKING line:151 — §11 SurfaceItem::Let + SurfaceLiteral span correction Cursor INLINE BLOCKING line:151: §11 claimed "every Surface variant carries SourceSpan" but live parse_surface.dag has: - SurfaceItem::Let { name, type_ann, expr } — no direct span - SurfaceLiteral = Int(String) | Bool(Bool) | String(String) — plain-tuple variants with no direct span Source-span provenance for these cases is via enclosing carrier: SurfaceLiteral wraps within `Literal { value, span }` at parse_surface.dag:150. Let-item inherits container span. INVARIANTS P2/P3 source provenance is structurally guaranteed via direct-OR-enclosing carrier, but my "every variant" overstatement obscured this. Fix: §11 corrected to "most Surface variants carry SourceSpan directly" + explicit Let + SurfaceLiteral exceptions noted + Step 2 PR scope audits whether exceptions are structural-honest (enclosing-carrier-provides-span) OR require substrate extension. Same recurring overstatement class as earlier "every SurfaceItem maps 1:1 to Declaration" (commit 61e2b67) — need to grep live substrate variant fields BEFORE claiming uniform shape. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * WIP: gunbc Director * docs(r3): cursor PR #3126 INLINE BLOCKING line:32 — GrammarSpec is concept, not carrier Earlier draft (now-merged PR #3126) framed `GrammarSpec` as a second declared `.dag` input type alongside `List<Token>`. Verified via grep that no `type GrammarSpec` exists anywhere under src/v3/ or dsl/ — the repo carries only `parse_tables.dag`'s 6 SG-2c table-families. Per cursor 2026-05-14T23:30:04Z inline finding, this violates INVARIANTS P2 (the Step-2 signature names a carrier the substrate doesn't declare). Reframed §3 (and downstream mentions in §3.2, §3 preamble line:33, §4.2 codex-correction recap line:165, §5.1 line:181, §12 Q6 line:344) so that: - Parse has ONE input at the API boundary: `List<Token>`. - "GrammarSpec" is a concept-level grouping for the 6 compile-time table-families in `parse_tables.dag`, not a substrate carrier and not a runtime parameter. - Step-2 signature stays `fn parse(tokens: List<Token>) -> Result<SurfaceModule, ParseDiagnostic>` per cfe842b (already applied in #3126); these edits remove the lingering "two input types" framing that contradicted that signature. Per Decision 3.B (b) compile-time parser tables: substrate authority is parse_tables.dag (6 table-families) consumed via direct table lookups inside the parser body — no runtime grammar value, no `GrammarSpec` carrier needed. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * docs(r3): codex PR #3138 BLOCKING — §4.3 + §16 internal contradictions resolved Codex review id 12391 on sha cd6e8d1 flagged two live statements of the already-rejected typed-state-with-coupled-diagnostics model still sitting inside the parse L2.5, contradicting the corrected Result-sum framing in §4.2 and §6 Step 2: 1. §4.3 still proposed a `SurfaceModule { items, diagnostics }` extension modeled on PB-4/PB-5 patterns. Reframed: §4.3 now states explicitly that parse-stage uses Result-sum (no diagnostics field on SurfaceModule), restates the cross-stage discriminator (Result-sum for fail-fast output domains: parse + emit; typed-state for structural output domains: lower + infer), and cites `parse_generated.rs:138` as the live shape. 2. §16 "Memory disciplines applied" bullet read "feedback_state_space_vs_behavioral_invariants (typed-state SurfaceModule at output)". Rewritten to "parse output is `Result<SurfaceModule, ParseDiagnostic>` — the type rules out partial-parse states by construction; SurfaceModule itself carries no diagnostic field per §4.3". Per `feedback_discipline_change_audit_all_contract_mentions`: when a contract changes (here: SurfaceModule extension dropped in favor of Result-sum), all §-internal restatements must be swept in the same diff or they leak through as authoritative parallel claims. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * docs(r3): codex PR #3127 BLOCKING — drop TokenizedSource extension + cite concrete P5 receipts Codex review id 12370 on sha d15e1f2 raised two load-bearing planning-shape findings on the tokenize L2.5. Addressed in this fix-forward branch (PR #3138) since PR #3127 is still open but accumulating cycles. Finding 1 — parallel boundary carriers (INVARIANTS P2 / Modeling Practices 3+5): §4.3 + §9 Step 2 + §12 Q6 named `TokenizedSource { tokens, diagnostics }` as the output, while §2/§7.2/§7.3 named `List<Token>`. Same misclassification I just removed from the parse L2.5 in PR #3138 §4.3: tokenize sits in the fail-fast output domain alongside PB-3 parse + PB-6 emit (a partial token list with a corrupt token in the middle is not a valid downstream input for parse), so the failure couples via `Result`, not into the structural carrier. Resolution: - §4.3 rewritten to ratify `Result<List<Token>, TokenizeDiagnostic>` — the live `tokenize_generated.rs:96` shape — with no `TokenizedSource` extension. - §9 Step 2 row signature updated to match; explicit "single canonical boundary carrier: List<Token> on the Ok branch" framing. - §12 Q6 resolved REJECTED in-doc (no operator ratification needed; disposition follows from the cross-stage discriminator that's also load-bearing in PR #3138 parse L2.5). - §16 memory-disciplines bullets rewritten parallel to PR #3138 parse §16: Result-sum, no diagnostics field on `List<Token>`. - §14 "Surfaces awaiting" trimmed Q6 from the operator-ratification list. Finding 2 — soft deferral of `regen_tokenize` retirement (INVARIANTS P5): deferral previously named "PB-Bootstrap-Process lane scope" without a concrete ROADMAP.md row. Updated §9 Step 2 + Step 4 rows to cite the named receipts: - `docs/design-pure-bootstrap-zero.md:116` (PB-Bootstrap-Process lane: author bootstrap.dag + generated trampoline; sized M). - `docs/design-pure-bootstrap-zero.md:118-123` (N=0 runtime verification gates). - ROADMAP.md:467 (Character-level under-consumption in tokenize + syntax authorities — phase-2 char-class retype owns the codegen-driver path). - ROADMAP.md:416 (Class 5 Gap 3 — top-level `ValueBody` boundary; gating substrate-capability for the phase-2 retype). - ROADMAP.md:53 (T-PB-A — non-test census → 0 floor). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * docs(r3): cursor PR #3126 BLOCKING line:119 — §6/§7.2/§15 Q7 sequencing resolved by PR #3077 merge Cursor inline BLOCKING at docs/design-parse-stage-l25-model.md:119 (sha at merge time of PR #3126) flagged a real internal contradiction: - §6 (lines 191, 207, 308) claimed "Step 2 (pipeline-slot declaration) is unblocked" - §7.2 (line 227) claimed "PR #3077 §12 Q7 must ratify before any Step 2 worker brief authoring" A worker reading the doc could land Step 2 (pipeline boundary) before the diagnostic carrier's P2/P3 failure shape was fixed. Resolution: PR #3077 (PB-4 lower L2.5) merged at 2026-05-15T00:21:19Z, carrying the §12 Q7 ratification of the Decision 2.B per-stage diagnostic extension path. The gate IS now satisfied at HEAD, so the resolution is fact-update (annotate Q7 as DONE with the merge timestamp) rather than retracting either §6 or §7.2. Edits: - §15 step 4: annotated "DONE 2026-05-15T00:21:19Z when PR #3077 merged" and added the explicit "Step 2 is now genuinely unblocked, not just procedurally next" framing so workers reading the sequence don't bypass the gate. - §7.2 line 227: rewritten from "Q7 must ratify before Step 2 brief authoring" (future tense, the contradiction surface) to "Gate satisfied 2026-05-15T00:21:19Z when PR #3077 merged; Step 2 worker brief authoring is unblocked at HEAD per §15 step 4." Cites the cursor finding as the resolution path. §6 unblocking statements stay as-is — they were correct at HEAD; the contradiction lived in §7.2's pre-merge framing. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * docs(r3): codex PR #3126 BLOCKING (sha 16d21f4) — Q7 cited at every Step 2 unblocking claim Codex BLOCKING finding 2 (sha 16d21f4, 216s thinking): the Q7 dependency was recorded in §7.2/§15 but not in the other Step-2-unblocking sites at §6 lines 191, 207, 308 — risking a worker reading "Step 2 unblocked" without also reading the Q7 prerequisite. Codex framing: "make Q7 a hard precondition wherever Step 2 is called unblocked, or split Step 2 into pre-Q7 and post-Q7 scopes with separate receipts." Chose the first option since PR #3077 has already merged (2026-05-15T00:21:19Z) and splitting into pre/post-Q7 scopes is no longer load-bearing. Annotated all three §6 sites: - Line 191 (Implication for PB-3 migration): cites gate + merge timestamp + explicit "must NOT be brief-authored before that merge timestamp." - Line 207 (Critical observation): cites the Step 2 gate as PR #3077 §12 Q7 + merge timestamp + P3 failure-shape consequence if violated. - Line 308 (Director-recommend phase list): cites gate + §7.2/§15 step 4 cross-refs + merge timestamp. Codex BLOCKING finding 1 (GrammarSpec carrier non-existence) verified already resolved at HEAD via commit c97dc15 — every GrammarSpec mention now explicitly marks it as a concept-not-carrier; Step 2 signature is `fn parse(tokens: List<Token>) -> Result<SurfaceModule, ParseDiagnostic>` with no GrammarSpec parameter. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * docs(r3): openai-pro PR #3126 BLOCKING (sha 16d21f4) — Step 3b/4 atomicity + Q1 ratification-pending status openai-pro REQUEST_CHANGES on PR #3126 sha 16d21f4 flagged three findings. Findings 1 + 2 (signature vs realization mismatch under LAYER MODEL + P2/P3 boundary discipline) were already resolved at HEAD by earlier fix-forward commits — Step 2 signature is now `fn parse(tokens: List<Token>) -> Result<SurfaceModule, ParseDiagnostic>` matching live `parse_generated.rs:138` with no GrammarSpec parameter and no diagnostics-coupled SurfaceModule extension (§4.3 Result-sum disposition). Finding 6 (TRACKED vs UNTRACKED DEBT — Step 3b/4 same-PR vs two-PR): §9 had both a "Step 3b/4 COMBINED" row (line 250) and a leftover separate "Step 4: Parity test" row (line 251) — internally contradictory. §15 also still sequenced Steps 3b + 4 as four separate authoring/dispatch/ratify beats (steps 12-17), contradicting §12 Q5's "same PR" decision and the explicit "Update to §15" note at §12 line 325. Resolution: collapsed §9 to one COMBINED row absorbing the parity-TestClaim mechanics + P5 dissolution receipt from the deleted Step 4 row; collapsed §15 steps 12-17 into single COMBINED authoring + dispatch + ratify (steps 12-14). Added explicit `feedback_paper_shrink_variants` reasoning in both sections. Finding 2.5 (PM intent — substrate-capability bundled vs separate): §12 Q1 line 288 said "Director-recommend: (b) bundled" while §13 line 340 listed substrate-capability as a non-goal of PB-3 and §15 step 11 had "WAIT for substrate-capability landing" — three sections, two different execution paths. Resolution: annotated Q1 as "PENDING operator/PM ratification" with explicit default-execution clause: until operator ratifies, the doc treats substrate-capability as path (a) separate lane (matching §13 + §15 + §9 row). If/when ratified to (b), §13 drops the non-goal and §15 step 11 collapses into the COMBINED Step 3b/4 brief. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * docs(r3): codex PR #3126 BLOCKING (sha 5619afa) — parse_tables.dag as single enumerated authority Codex caught me copying the prose summary at parse_tables.dag:23-29 (which enumerates only SG-2c-numbered families) instead of grepping the live `^type [A-Z]` declarations. Result: SoftKeywordIdentRow (line 334) was missing from §3.2 / §5.1 / §6 / §12 because it lacks an SG-2c-N number in the prose summary. Per `feedback_parallel_representation_debt`: structural fix is to stop hand-enumerating in the doc — cite parse_tables.dag itself as the single enumerated authority and use `type`-declaration line-anchors for the worked example, not a hand-maintained count. Edits: - §3.2 §"Live substrate authority": replaced the SG-2c-numbered bullet list with `type`-declaration line-anchor enumeration including SoftKeywordIdentRow at parse_tables.dag:334 + the supporting enum BinaryOpLevel at line 133. Added codex-finding callout explaining the miss + the discipline shift. - §3 preamble line:33, §3.2 line:45 callout, §3.2 line:57 framing, §3.2 §"Substrate authority" line:71, §5.1 line:171-180, §12 Q2 line:298, §12 Q6 line:334: all hardcoded "6 table-families" counts dropped; doc now points readers to §3.2 enumeration / `parse_tables.dag` directly. - §5.1 sub-enumeration list (the parallel 6-item list at lines 173-178) deleted; replaced with redirect to §3.2 + restated 3a-vs-3b/4 scope split. Code-level check before commit: `grep -nE '^type [A-Z]' src/v3/compiler/parse_tables.dag` returns 7 types: BinaryOpLevel (133), BinaryOpRow (167), TopLevelItemKwRow (289), SoftKeywordIdentRow (334), BracketRow (385), PrimaryPrefixRow (449), PrimaryAtomRow (486). Doc enumeration matches. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * docs(r3): codex PR #3138 BLOCKING (sha f08b952) — bind TokenizeDiagnostic to live CharClass authority Codex Finding 1 (sha f08b952, 216s thinking): the §4.2 TokenizeDiagnostic draft and the §5.1/§5.2 headings used `ScannerCharClass` / `ScannerClassRef` — names that exist only as the *generated Rust enum spelling*, not as a declared .dag substrate type. Verified via grep: grep -rn '^type CharClass\|^type ScannerC' dsl/ src/v3/ returns ONE authority: `dsl/std/unicode.dag:62` type CharClass = Whitespace | Digit | IdentStart | IdentContinue consumed at `src/v3/compiler/tokenize.dag:103` data ascii_scan_order: List<CharClass> = [Whitespace, Digit, IdentStart, IdentContinue] There is no `ScannerCharClass` declaration anywhere — that name was copied from generated Rust without grep-verification, the same failure mode as `feedback_grep_substrate_before_naming_ratification` (carrier-name collision discipline). Resolution: - §4.2 TokenizeDiagnostic carrier: `expected_class: ScannerClassRef` → `expected_class: CharClass`, dropped the `type ScannerClassRef = ScannerCharClass` alias entirely; added a codex-finding callout citing the substrate authority + naming the failure mode. - §5.1 heading "Byte → ScannerCharClass dispatch" → "Byte → CharClass dispatch"; bullets unchanged; added line-anchor cites for the substrate authority + explicit "NOT ScannerCharClass" disclaimer. - §5.2 heading "ScannerCharClass → token-recognition state machine" → "CharClass → token-recognition state machine". Finding 2 (TokenizedSource not reconciled with parse input contract): no new fix required — already resolved by commit 6adb992 (TokenizedSource extension dropped entirely; tokenize uses Result<List<Token>, TokenizeDiagnostic>; List<Token> is the single canonical boundary carrier consumed by parse). Codex was reviewing sha f08b952, which predated the TokenizedSource drop. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * docs(r3): cursor PR #3138 INLINE BLOCKING line:188 — clarify §7.3 chain is Ok-branch propagation Cursor INLINE at sha f08b952 worried that §7.3's cross-stage chain "tokenize → List<Token> → parse → ..." was inconsistent with §4.3's TokenizedSource carrier (diagnostics not flowing forward). At HEAD the TokenizedSource extension is dropped (commit 6adb992); tokenize uses Result<List<Token>, TokenizeDiagnostic>, so List<Token> IS the canonical Ok-branch payload that flows forward and Err branches terminate the pipeline fail-fast. To make this explicit at §7.3 (instead of leaving readers to infer it from §4.3), annotated the chain with: - "Ok-branch propagation; Err branches are stage-terminal fail-fast per §4.3 Result-sum discriminator" framing prefix. - Per-stage Result/typed-state annotations: tokenize/parse show Result<Ok, Err>; lower/infer show typed-state structural-output; emit shows Result<EmittedArtifact, EmissionDiagnostic>. - Explicit "on any stage's Err branch the pipeline aborts at that stage (no partial-output propagation across boundaries)" trailer. This makes the chain self-consistent vis-a-vis §4.3 without requiring the reader to walk back-and-forth, and prevents future readers from re-introducing a TokenizedSource-shaped extension to "make diagnostics flow forward" — they already do, just via the Err branch terminating the pipeline. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * docs(r3): openai-pro PR #3127 BLOCKING (sha d15e1f2) — character-level scaffold dissolution trigger openai-pro REQUEST_CHANGES on sha d15e1f2: §1 line:26 character-level under-consumption scaffold named the problem but lacked a checkable dissolution trigger. SG-1a scaffold above had the right shape — "once those bodies lower structurally under compile_to_dag, delete the raw-text extractor + derive directly from lowered Dag in same PR." Character-level scaffold just said "PB-2 Step 4 carries this scope" — a lane assignment, not a trigger. Resolution: rewrote §1 item 2 with the same SG-1a-shape trigger structure: - Substrate-consumption condition (a): scanner classes / string escape / local punctuation retype to `dsl/std/unicode.dag` `CharClass` / `char_in_class` (concrete field retypes named: `StringEscapeSpec.suffix: Char`, `LocalPunctSpec.pattern: List<Char>`, `string_literal_delimiter: Char`). - Codegen-driver condition (b): `tokenize_generated.rs` no longer emits hidden `byte.is_ascii_*` predicates because the driver reads class facts structurally from lowered `tokenize.dag`. - Same-PR dissolution: delete the parallel character-predicate scaffold in the same PR that flips substrate consumption — no Rust-and-`.dag` coexistence per `feedback_paper_shrink_variants`. - Cross-ref to §9 Step 4 gating prereqs: ROADMAP.md:467 + ROADMAP.md:416 Class 5 Gap 3 + std.unicode bootstrap/load-set decision (already cited in §9 from earlier commit 6adb992). Per openai-pro's framing: "small fix — mirror the SG-1a scaffold wording by naming the exact substrate-consumption condition and same-PR deletion receipt for the hidden Rust character predicates." Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * WIP: gunbc Director * docs(r3): cursor PR #3127 APPROVE_WITH_COMMENTS — §14 + §15 Q6-already-rejected sweep Cursor review id 12405 (APPROVE_WITH_COMMENTS) caught the same `feedback_discipline_change_audit_all_contract_mentions` failure mode recurring: §12 Q6 was resolved REJECTED in commit 6adb992, and §14 "Surfaces awaiting" + §12 Q6 heading + §9 Step 2 row were updated, but two §-internal contract restatements were missed: - §14 acceptance criterion 11: "Operator/PM ratification on §12 Q1-Q6" - §15 step 1: "Operator / PM-delegate ratifies §12 Q1-Q6" Both contradicted §12 Q6 + §14 "Surfaces awaiting" (which already said "Q1-Q5 only"). A worker reading §14/§15 could schedule sign-offs on Q6 after it was already resolved-rejected elsewhere. Resolution: both sites now say "Q1–Q5" with the explicit Q6-rejected crossref + "see §14/§15 for same scoping" pointer at the §14 criterion so the three sections agree internally. Cursor verdict was APPROVE_WITH_COMMENTS (substantive APPROVE — "fix the checklist/sequence so every section agrees Q6 is closed"); the exploratory volatile-line-anchor note is harmless and out-of-scope for this PR. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * docs(r3): codex PR #3138 BLOCKING (sha 887c696) — 3 findings swept across 3 L2.5 docs Codex review id (sha 887c696, 333s thinking) flagged three findings, all `feedback_discipline_change_audit_all_contract_mentions` recurrences where partial sweeps left §-internal contradictions. Finding 1 — infer doc cross-stage trigger leak: §4.2 InferDiagnostic dissolution trigger said "when Step 2 worker brief enumerates the full variant set against `parse_generated.rs` Diagnostic::ParseError, lower.rs Diagnostic construction sites, and infer.rs Dag::mark_unresolved emission sites." That cross-stage trigger surface is wrong for the infer-specific scaffold. Narrowed to infer-only: "against `src/v3/compiler/src/infer.rs` Diagnostic construction sites + `Dag::mark_unresolved` emission sites (infer-stage only)." Parse and lower have their own per-stage carriers + own Q7 mapping; this doc no longer reaches into their dissolution-trigger surface. Finding 2 — parse + tokenize coproduct receipts: `ParseDiagnosticKind` (parse §4.2) and `TokenizeDiagnostic` (tokenize §4.2) sums were declared without the 🟡 SCAFFOLD / 🟢 TERMINAL classification + dissolution trigger that the infer doc carries (per modeling-discipline Practice 4 + `feedback_coproduct_dissolution`). Added matching scaffold receipts to both: 🟡 SCAFFOLD at PROPOSED stage with stage-local dissolution trigger (Step 2 brief enumerates against parse_generated.rs / tokenize_generated.rs Diagnostic::* construction sites — stage-only, not cross-stage); promote to 🟢 TERMINAL when full variant set lands. Both also carry the anti-bridge note per Q6.5. Finding 3 — tokenize Q7 reconciliation: The parse doc has the "Q7 DONE 2026-05-15T00:21:19Z" annotation at §15 step 4 (commit f85fa1f) but the tokenize doc still framed Q7 as a pending lane dependency at §4.2 line:113 ("Lane dependency"), §15 step 3, and §14 "Surfaces awaiting". Annotated all three: - §4.2 "Lane dependency": Q7 DONE timestamp + "TokenizeDiagnostic per-stage variant authoring is the remaining lane work." - §15 step 3: full DONE annotation matching parse doc §15 step 4 shape + cross-ref to the parse doc. - §14 "Surfaces awaiting": strikethrough + DONE annotation. PR #3127 also carries the tokenize doc; same edits will port there in a companion commit. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * docs(r3): cursor PR #3138 INLINE BLOCKING line:372 — §16 Surfaces awaiting Q7 contradiction Cursor inline at sha 887c696 caught the symmetric finding to the codex 5-finding BLOCKING #3: parse-doc §15 step 4 already annotated Q7 as DONE (commit f85fa1f) but parse-doc §16 "Surfaces awaiting" still listed Q7 as pending. Same `feedback_discipline_change_audit_all_contract_mentions` sweep failure — the tokenize doc had three sites carrying the pending framing (commit e9739ea fixed those) but the parse doc's §16 site was missed in the original Q7-DONE sweep. Resolution: §16 bullet now strikes through + "DONE 2026-05-15T00:21:19Z (PR #3077 merged carrying Q7 ratification; see §15 step 4)" — same shape as the tokenize doc's §14 "Surfaces awaiting" Q7-DONE annotation landed in e9739ea. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…+ cursor inlines (#3141) * docs(r3): PB-2 tokenize pipeline-stage L2.5 domain model — DRAFT for ratification Director-tier L2.5 model for PB-2 tokenize per operator 2026-05-14 ratification (Decision 1.A scoping = Option A). PB-2 is the FURTHEST-ALONG pipeline stage — substrate authority already lives in `.dag`: - src/v3/std/tokenize.dag (Token + TokenKind taxonomy; LIVE 143 lines) - src/v3/compiler/tokenize.dag (tokenizer implementation; LIVE 154 lines) - src/v3/compiler/src/tokenize_generated.rs (AUTO-GENERATED; 362 lines) This is the END STATE that all other pipeline-stage migrations target. PB-2 L2.5 is correspondingly lighter — mostly verification + residual hand-Rust retirement, NOT new substrate authoring. Distinct §9 4-step framing: - Step 3 = VERIFY substrate completeness (audit per feedback_paper_shrink_variants) - Step 4 = HANDOFF/RETIRE residual hand-Rust scaffolding (coordinates with PB-Bootstrap-Process lane for codegen-driver retirement) Captures audit dimensions explicitly: - scanner-class definitions = declarative byte-pattern membership - recognition tables = closed-axis enums - state machine = structural transitions - no V2 `pub mod tokenize` absorption check §12 Q1: codegen-driver retirement scope — Director-recommend PB-Bootstrap-Process handles all codegen-driver retirement cross-cuttingly (not per-stage paper-shrink risk). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * docs(r3): §12.6 citation fix — tokenize is PB-2 lane scope per design-pure-bootstrap-zero.md Per cursor PR #3085 finding: §12.6 explicitly tables only 4 pipeline-stage migrations (emit→lower→infer→parse); tokenize is per design-pure-bootstrap-zero.md PB-2 lane. Same fix as PR #3085 commit 89fbd7a2a applied here. INVARIANTS P1 — documentation must not overstate authority cites. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * docs(r3): preemptive fix for PR #3126 codex BLOCKING propagation — PB-2 live state honesty Same class as codex INLINE BLOCKING #3126 finding 1 (live state honesty for diagnostic coupling) applied preemptively to PB-2 tokenize L2.5. PB-2 §4.3 had "diagnostics coupled INTO List<Token>" framing which would overstate the live carrier shape (bare List<Token> has no diagnostic field; tokenize_generated.rs:96 today returns Result<Vec<Token>, Diagnostic>). Fix: §4.3 reframed with PROPOSED substrate extension explicit — new `TokenizedSource { tokens, diagnostics }` wrapper carrier as the typed-state output. Step 2 brief includes wrapper authoring in pipeline-slot PR scope. Same discipline as PR #3126 commit bdff8c500. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * docs(r3): cursor PR #3077 — fix PB-2 lane citation (design-pure-bootstrap.md not -zero.md) Per cursor APPROVE_WITH_COMMENTS /api/reviews/12087: PB-2 lane is defined in docs/design-pure-bootstrap.md §"PB-2 — tokenize retire" (line ~134), NOT docs/design-pure-bootstrap-zero.md. The -zero.md doc has Subsumed-lanes list with PB-1/PB-4/PB-5/PB-6 but NOT PB-2. Propagated fix applies same cite-error correction as PR #3066 §1.8 discipline: cite the actual doc, not an adjacent doc with similar name. INVARIANTS P2 single-authority-citation. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * docs(r3): fix cursor PR #3127 BLOCKING contradictions + add §12 Q6 Cursor APPROVE_WITH_COMMENTS (/api/reviews/12093) caught two substantive contradictions I introduced when adding TokenizedSource in commit 2b9756bb5: 1. §4.3 vs §9 Step 2 signature mismatch — §4.3 said `-> TokenizedSource` but §9 Step 2 row still said `-> List<Token>`. Same `feedback_discipline_change_audit_all_contract_mentions` issue that's recurred 4x this session. 2. §4.3 referenced "§12 Q-new" but §12 only had Q1-Q5; broken anchor. Fix: 1. §9 Step 2 row updated: signature `-> TokenizedSource` with wrapper carrier shape `{ tokens, diagnostics }` per §4.3 2. §4.3 anchor updated: "§12 Q6" (resolved) 3. Added §12 Q6: TokenizedSource carrier shape ratification — (a) wrapper record vs (b) per-Token diagnostic coupling; Director-recommend (a) for PB-3 SurfaceModule parallelism 4. §14 + §15 + §16 Q-list refs updated to Q1-Q6 Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * docs(r3): fix codex BLOCKING PR #3127 — Token shape + Q4 audit boundary Codex REQUEST_CHANGES (sha b881de23) with 2 substantive findings: 1. §4.1 Token shape claim "optional lexeme: String" — wrong per live substrate at src/v3/std/tokenize.dag:65-67. Live Token has 2 fields only (kind + span); lexeme-content lives ON the TokenKind variants (Ident(String) / IntLit(String) / etc.). Fix: corrected §4.1 to reflect live carrier shape; payloads on TokenKind variants noted explicitly. 2. §12 Q4 substrate-completeness audit scoped only to tokenize_generated.rs — missed the regen_tokenize codegen- driver boundary. If regen_tokenize carries scanner-logic decisions (rather than mechanical template-rendering of substrate facts), the substrate isn't complete — the driver IS hand-Rust scanner logic in disguise. Fix: Q4 audit extended with (d) regen_tokenize codegen- driver logic audit + (e) ROADMAP.md deferral row option per feedback_paper_shrink_variants P5 receipt discipline. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * docs(r3): fix codex BLOCKING PR #3127 — TokenizeDiagnostic PROPOSED + scaffold disclosure Codex REQUEST_CHANGES (sha b881de23, full body) caught 2 substantive overstatements: 1. §2 line 46 claimed "tokenize failures produce typed TokenizeDiagnostic variants" — but live tokenize_generated.rs:96 returns generic `Result<Vec<Token>, Diagnostic>` with `Diagnostic::TokenizerError { message, span, correction }`. Typed TokenizeDiagnostic is a PROPOSED extension, not live state. Fix: §2 reframed with live state explicit + TokenizeDiagnostic marked PROPOSED per PR #3077 §12 Q7 ratification path. 2. §1 line 22 + §6 + §9 Step 2 line 198 framed PB-2 as "mostly verification" — but live tokenize.dag:16-30+ has TWO explicit tracked scaffold zones: - SG-1a: regen_tokenize parses raw source text for dag_keyword_set / dag_operators (ValueBody::Unparsed) - Character-level under-consumption: StringEscapeSpec / LocalPunctSpec.pattern / string_literal_delimiter as opaque Strings; hidden Rust character predicates (byte.is_ascii_digit etc.) at tokenize_generated.rs:15-22 leaking through codegen Residual hand-Rust is NOT just the codegen artifact — it includes (a) regen_tokenize logic, (b) SG-1a raw-text-extractor scaffold, (c) character-predicate scaffold leaking through codegen. Fix: §1 + §6 + §9 Step 2 reframed honestly. PB-2 is "FURTHER ALONG but not complete"; Step 4 carries scaffold-retirement scope, not just codegen-artifact retirement. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * docs(r3): post-merge fix-forward — §16 + §9 Step 2 internal contradictions Two post-merge doc-internal contradictions caught by reviewers after operator merged PR #3077 / #3126 / #3085 at 2026-05-15T00:21Z. **PR #3077 PB-4 lower §16 fix**: §16 "Memory disciplines applied" bullet said "diagnostics coupled INTO PreInferDag via biconditional" — but §4.3 (per openai-pro DiagnosticAnchor fix commit b812db91b) constrains biconditional to PortAnchor-only. Other anchor kinds (DeclarationAnchor / RecordFieldAnchor / SurfaceFormAnchor) couple without port-state. Fix: §16 bullet honors §4.3 anchor-typed framing. **PR #3126 PB-3 parse §9 Step 2 fix**: §9 Step 2 row described diagnostics as "coupled INTO SurfaceModule" as if live — §4.3 correctly marks it PROPOSED. Same feedback_discipline_change_audit_all_contract_mentions pattern that's recurred this session. Fix: §9 Step 2 row clarified — "PROPOSED extension per §4.3"; Step 2 PR scope includes authoring the diagnostics field extension, NOT a live coupling. Per feedback_discipline_change_audit_all_contract_mentions: when a substantive fix changes a discipline framing, audit ALL sections (framing + contract + handoff). Post-merge audit surfaced these residual contradictions. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * docs(r3): post-merge fix-forward — PR #3126 codex BLOCKING (GrammarSpec parallel-authority + fail-closed weakening) Codex REQUEST_CHANGES on already-merged PR #3126 (/api/reviews/12175): 2 substantive findings on the post-merge doc. **Finding 1 (P2 violation — GrammarSpec parallel authority)**: §3.2 says GrammarSpec is compile-time-only, NOT runtime- interpreted (per Decision 3.B (b) operator override). But the proposed stage contract still took `grammar: GrammarSpec` as runtime input. Creates two authorities (compiled parser tables + runtime GrammarSpec value). Fix: §4.3 signature reframed to `fn parse(tokens: List<Token>) -> Result<SurfaceModule, ParseDiagnostic>` — NO runtime GrammarSpec input. Compile-time generated parser tables consumed via internal dispatch. Step 2 + Step 4 rows updated. **Finding 2 (P3 + Practices 1/2 — fail-closed weakening)**: Live parser at parse_generated.rs:138 returns `Result<SurfaceModule, Diagnostic>` (fail-closed; aborts on first error). Earlier draft proposed `SurfaceModule` with embedded diagnostics — would let partial-parse states be constructible + let downstream observe "success" output after parse failure. Violation of fail-closed discipline. Fix: signature preserves Result-sum (matches live + emit's pattern). Distinguished cross-stage: - Result-sum (parse + emit): fail-fast output domain - Typed-state-with-coupled-diagnostics (lower + infer): structural output domain where partial-failure IS valid intermediate Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * docs(r3): cursor PR #3126 post-merge APPROVE_WITH_COMMENTS — §4.1 + §16 fail-closed honesty Cursor caught 2 more post-merge contradictions on PR #3126: 1. §4.1 line 81 "construction-time invariant" talks about "ParseDiagnostic in the diagnostic stream" tied to SurfaceModule path — but §5.2 + live parse_generated.rs:138 use Result<SurfaceModule, Diagnostic>. §4.1 reads as claim about today's plumbing. Fix: §4.1 reframed — live boundary explicit (Result-sum); construction-time invariant scoped to Ok-arm SurfaceModule + Err-arm ParseDiagnostic, no partial-parse with embedded diagnostics. 2. §16 line 397 cites C-8 as "ParseDiagnostic coupled INTO SurfaceModule" without qualifier — but §4.3 (post codex REQUEST_CHANGES fix) constrains to Result-sum. Fix: §16 bullet honors §4.3 Result-sum framing; cross-stage discriminator named. Same recurring feedback_discipline_change_audit_all_contract_mentions pattern — substantive fix to §4.3 + §9 Step 2 left §4.1 + §16 inconsistent. Post-merge audit catches. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * docs(r3): cursor PR #3085 INLINE BLOCKING — TypeConnective extension stop-signal Cursor INLINE BLOCKING caught §3.2 line 66 "rules extend automatically" weakens substrate-extension stop-signal. Thesis discipline: a 7th TypeConnective variant requires explicit C1 audit + named infer-rule receipt. Fix: §3.2 reframed. New TypeConnective variants do NOT extend automatically; require explicit C1 substrate-extension audit + named infer-rule receipt for the new variant's structural inference behavior. Per-variant structural facts means new variants need new per-variant facts, NOT silent inheritance. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * docs(r3): cursor PR #3085 INLINE BLOCKING — AlgebraAxis + InferDiagnostic Practice 4 classification Cursor INLINE BLOCKING /api/reviews/12218 (line:112): proposed substrate coproducts (AlgebraAxis + InferDiagnostic) lack 🟢/🟡/🔴 classification + ledger/trigger per modeling-discipline Practice 4 (Coproduct dissolution). Fix: added 🟡 SCAFFOLD classification + named dissolution trigger for both: AlgebraAxis 🟡 SCAFFOLD: - Trigger: Step 2 brief enumerates full algebra-axiom set against infer.rs check sites + verifies coverage parity with live verification.dag:146 AlgebraicLawKind 3-variant subset → promote to 🟢 TERMINAL. InferDiagnostic 🟡 SCAFFOLD: - Trigger: Step 2 brief enumerates full variant set against parse_generated.rs / lower.rs / infer.rs diagnostic emission sites → promote to 🟢 TERMINAL. - Anti-bridge per Q6.5: does NOT collapse into CompilerDiagnosticKind without substrate-extension ratification per PR #3077 §12 Q7. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * docs(r3): cursor PR #3077 INLINE BLOCKING — §5.1 SurfaceItem allocation correction Cursor INLINE BLOCKING /api/reviews/12251 line:130: §5.1 said "every SurfaceItem variant maps 1:1 to a Declaration placeholder" but live lower.rs:2950-2958 explicitly skips Let/Module/Import in collect_symbols. Verified via Read of lower.rs:2956-2958: SurfaceItem::Let { .. } => continue, SurfaceItem::Module { .. } => continue, SurfaceItem::Import { .. } => continue, Fix: §5.1 reframed — DeclarationAllocating variants (Fn / FnExternalBody / Data / TypeAtom / TypeRecord) map to placeholders; NonDeclarationAllocating variants (Let / Module / Import) skip allocation per live lower.rs behavior. Let-bodies lower to Bind expressions in Pass 2; Module/Import are parsed-facts preserved but un-declared. Earlier "every SurfaceItem variant" framing overstated; would have steered Step 2/3 worker into wrong allocation contract. Per INVARIANTS P1/P2 live-state honesty + facts-flow-forward. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * docs(r3): cursor PR #3077 INLINE BLOCKING — ElaborationSpec scope broadened Cursor INLINE BLOCKING line:33: ElaborationSpec was defined only as Surface→Behavior recipe mapping, but lower constructs Declarations / TypeConnectives / BranchPatterns / Bindings as well. Non-Behavior lowering decisions outside declared authority violates THESIS substrate ownership + INVARIANTS P2. Fix: §3.2 ElaborationSpec scope broadened to ALL lowering decisions: 1. SurfaceItem → Declaration recipes (Fn / Data / Type variants + Let/Module/Import skip-allocation per §5.1) 2. SurfaceType → TypeConnective recipes (Atom / Arrow / Compose / Disj construction) 3. SurfaceExpr → Behavior recipes (Value / Transform / Branch / Loop / Bind construction) 4. SurfacePattern → BranchPattern recipes (ResolvedVariant / UnresolvedVariant / record-pattern construction) 5. Binding-site rules (Bind params + result_port construction) ElaborationSpec is single-authority across ALL axes; no axis lives in implementation-tier hand-Rust. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * docs(r3): cursor PR #3126 APPROVE_WITH_COMMENTS — §7.1 ordering vs independence clarification Cursor APPROVE_WITH_COMMENTS /api/reviews/12265 line 197: §7.1 mixed two claims: - "parse migrates AFTER tokenize substrate-side stable" (ordering) - "PB-3 parse migration is independent of PB-2 tokenize migration status" (independence) Read as contradictory by reviewers. Need one coherent story. Fix: §7.1 reframed with two distinct axes explicit: 1. Substrate-stability ordering (SELF_HOSTING.md §2 bottom-up): tokenize Token carrier shape must be stable BEFORE parse migrates. Already true at HEAD (tokenize.dag:65-67 declares live carrier). ✓ 2. Migration-timing independence (parallel-dispatch axis): PB-3 parse migration ships in parallel with PB-2 residual-retirement work (SG-1a + character-level scaffold + codegen-driver retirement per PB-2 L2.5 §1). What parse needs is the stable Token CARRIER; PB-2's migration is about retiring residual hand-Rust, not changing the carrier. Both claims coherent on the axis split; not contradictory. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * docs(r3): cursor PR #3126 INLINE BLOCKING — ParseDiagnostic SourceSpan structural requirement Cursor INLINE BLOCKING /api/reviews/12277 line:65: ParseDiagnostic variants like UnexpectedToken lacked SourceSpan field; List<ParseDiagnostic> cannot satisfy fail-closed source attribution structurally without span on every variant. INVARIANTS P2/P3 violation. Fix: every ParseDiagnostic variant now carries SourceSpan structurally: - UnexpectedToken: added span: SourceSpan - UnterminatedConstruct: opener_span: SourceSpan (already present) - InvalidLiteral: added span: SourceSpan - DuplicateRecordFieldLabel: added span: SourceSpan (current site) + prior_span: SourceSpan (prior site; both required) Per INVARIANTS P2/P3 fail-closed source attribution discipline: every diagnostic emission carries structural source-span provenance; not optional. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * docs(r3): cursor PR #3126 INLINE BLOCKING — Token authority cite phantom-reference fix Cursor INLINE BLOCKING /api/reviews/12279 line:29: §3.1 cited `src/v3/compiler/src/tokenize.rs` as "current hand-Rust" for Token carrier — but `tokenize.rs` (without _generated suffix) doesn't exist. Live state has tokenize.dag (live substrate) + tokenize_generated.rs (codegen artifact). Per design-pure-bootstrap.md PB-2 lane: tokenize retire has substantially landed. The reference was an earlier-draft phantom from when Token-was-hand-Rust framing was the assumption. Fix: §3.1 reframed — Token type lives in LIVE src/v3/std/tokenize.dag:65-67 shared taxonomy; tokenizer implementation also live at src/v3/compiler/tokenize.dag (154 lines); codegen artifact at tokenize_generated.rs. tokenize.rs phantom reference removed explicitly. PB-2 substantially landed per design-pure-bootstrap.md; residual scaffold-retirement scope per PB-2 L2.5 PR #3127. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * docs(r3): cursor PR #3126 INLINE BLOCKING — Step 2 pipeline-slot target fix (compiler.dag → pipeline.dag) Cursor INLINE BLOCKING /api/reviews/12281 line:138: §9 Step 2 referenced generic "compiler.dag" but dsl/gunbc/compiler.dag:24 explicitly directs internal pipeline (Tokenize → Parse → ...) to src/v3/compiler/pipeline.dag, NOT generic compiler.dag. Worker briefs authored against this doc would target the wrong file for pipeline-slot declaration. P2 single-authority violation. Fix: §9 Step 2 row in ALL 4 L2.5 docs (PB-2 / PB-3 / PB-4 / PB-5) updated: - "declared in compiler.dag" → "declared in src/v3/compiler/pipeline.dag (per dsl/gunbc/compiler.dag:24 — internal pipeline lives in pipeline.dag, NOT generic compiler.dag)" - substrate column: "compiler.dag refinement" → "pipeline.dag refinement" - §13 "Step 2 (pipeline-slot in compiler.dag)" → "pipeline-slot in src/v3/compiler/pipeline.dag" Same phantom-citation class as the tokenize.rs phantom (commit 8ae37b4a5): I cited generic file path without verifying which specific file is authoritative per project structure. Should have grep'd dsl/gunbc/compiler.dag header notes before authoring. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * docs(r3): cursor PR #3126 INLINE BLOCKING — Step 3b/4 phasing P5 receipt unambiguity Cursor INLINE BLOCKING /api/reviews/12283 line:181: Q5 said Step 3b "full parser body .dag migration + parser body deletion in same PR", but §15 sequence schedules Step 4 parity/deletion AFTER Step 3b merges. P5 dissolution receipt ambiguous. If Step 3b lands .dag parser body BEFORE Step 4 deletes Rust parse() body, Rust + .dag parser bodies coexist temporarily — paper-shrink-relocation risk per feedback_paper_shrink_variants. Fix: 1. §9 Step 3b row reframed as "Step 3b/4 COMBINED" — atomic single PR (full .dag parser body + parity TestClaim + parse_generated.rs:138 deletion + census shrink). Cannot land .dag parser body before Rust deletion. 2. §12 Q5 phasing clarified: - Phase 3a (separate PR): grammar table extension; P5 receipt = ROADMAP deferral row naming Step 3b/4 as future-receipt - Phase 3b/4 COMBINED (single PR): atomic substrate substitution 3. §9 + §15 update notes: sequence collapses steps 12-17 into single dispatch+merge for combined phase Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * docs(r3): codex PR #3126 high-level BLOCKING findings 1 + 2 Codex high-level BLOCKING (sha 140eb6bb) had 4 findings: - Findings 3 + 4 already addressed in PR #3138 commits 015977347 + a1607a88d - Findings 1 + 2 addressed in this commit **Finding 1 (Diagnostic kind/record conflated)**: §4.2 ParseDiagnostic was modeled as variants-directly with span + kind-fields mixed. Live Diagnostic at diagnostics.dag:150 uses record-wraps-kind pattern (`{ kind, span, message, correction }`). Need consistent shape. Fix: refactored to record-wraps-kind: - `type ParseDiagnostic { kind: ParseDiagnosticKind, span: SourceSpan }` - `type ParseDiagnosticKind = UnexpectedToken | UnterminatedConstruct | InvalidLiteral | DuplicateRecordFieldLabel | ...` Span lives on ParseDiagnostic record (single source of truth); variant-specific spans (opener_span / prior_span) remain on kind variants where meaningful. **Finding 2 (PB-2 §6 obsolete sibling-lane assumption)**: §6 line 198 said "PB-2 Tokenize | src/v3/std/tokenize.dag (NEW per PB-2 L2.5)" — but tokenize.dag is ALREADY LIVE per design-pure-bootstrap.md §"PB-2 — tokenize retire" (substantially landed). Fix: §6 prereq table row updated to reflect LIVE state. PB-2's residual scope is scaffold-retirement (SG-1a + character-level + codegen-driver per PB-2 L2.5 §1), not carrier authoring. PB-3 consumes the live Token carrier; carrier shape stable across PB-2 residual-retirement timing. Findings 3 + 4 already addressed: - Finding 3 (pipeline.dag target): commit 015977347 - Finding 4 (Step 3b/4 atomic vs sequential): commit a1607a88d Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * docs(r3): cursor PR #3126 APPROVE_WITH_COMMENTS — phantom "module-level metadata" removed Cursor APPROVE_WITH_COMMENTS line:79: §4.1 said "SurfaceModule (verified live) carries List<SurfaceItem> + module-level metadata" — but live parse_surface.dag:29 has ONLY `{ items: List<SurfaceItem> }`. No metadata fields. Phantom addition violated INVARIANTS P1 live-state honesty. Fix: §4.1 reframed to match live carrier exactly. Same phantom-addition class as tokenize.rs phantom (commit 8ae37b4a5). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * docs(r3): codex PR #3085 high-level BLOCKING findings — AtomPayload 5-variant + diagnostic-table PROPOSED Codex high-level BLOCKING (sha bf4d3152) — 2 substantive findings: **Finding 1 (AtomPayload stale)**: §2 + §5 cited infer.rs:10 top-comment "Atom(Identifier { name, resolved })" — but live substrate.dag:87 has 5-variant AtomPayload sum: Literal | UnresolvedIdentifier | ResolvedByStructure | ResolvedByName | TypeParam. infer.rs top-comment is STALE vs live substrate. My doc inherited the drift. Fix: §2 enumeration corrected to all 5 AtomPayload variants per live substrate.dag:87. **Finding 2 (diagnostic-table PROPOSED, not live)**: §2 + §4.1 + §4.3 said "diagnostics.contains(port_id) biconditional" as if live — but Dag at substrate.dag:525 has ONLY { declarations, nodes, ports, clusters }. NO diagnostics field. Diagnostic-table is PROPOSED substrate extension. Fix: §2 fail-closed note flagged PROPOSED — Step 2 PR scope includes `diagnostics: Map<PortId, Diagnostic>` field extension to Dag, OR PB-Substrate prereq adds it before PB-5 dispatch. Same recurring feedback_grep_carrier_field_before_coupling_claim discipline (PR #3126 SurfaceModule analogous case); needed to grep type Dag fields BEFORE claiming the diagnostics field exists. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * docs(r3): cursor PR #3085 INLINE BLOCKING line:94 — §4.1 + §4.3 PROPOSED diagnostic-table marking Cursor INLINE BLOCKING line:94: §4.1 + §4.3 said "diagnostics coupled INTO InferredDag" without flagging the diagnostic-table as a substrate extension. Live Dag at substrate.dag:525 has { declarations, nodes, ports, clusters } — NO diagnostics field. Earlier commit c0d96af25 added PROPOSED marking only in §2; §4.1 + §4.3 needed same treatment. Fix: §4.1 + §4.3 reframed with explicit PROPOSED substrate- extension marking + reference to §2 for extension scope. Construction-time invariant + structural coupling are both contingent on the substrate-extension landing (Step 2 PR scope or PB-Substrate prereq). Same recurring feedback_grep_carrier_field_before_coupling_claim discipline applied to §4.1 + §4.3 consistently with §2. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * docs(r3): codex PR #3077 high-level BLOCKING — Practice 4 classifications for PB-4 coproducts Codex high-level BLOCKING (sha b812db91): "Diagnostic substrate shape was repaired around anchoring but not re-audited as new substrate type declarations" — meaning DiagnosticAnchor + LowerDiagnostic + SurfaceFormRef + IdentifierRef need 🟢/🟡/🔴 classifications per modeling-discipline Practice 4 (Coproduct dissolution). Same pattern as PB-5 fix in commit 040681f21 (AlgebraAxis + InferDiagnostic) applied here. Fix: added classifications + dissolution triggers: - SurfaceFormRef 🟢 TERMINAL: closed-axis sum over live Surface* carriers; no further dissolution. - IdentifierRef 🟡 SCAFFOLD: dissolution trigger = Step 2 brief enumerates full identifier-kind set against lower.rs identifier-resolution sites; promote to 🟢 TERMINAL when SurfaceVarRef + TypePathRef + ModulePathRef cover actual axes. - LowerDiagnostic 🟡 SCAFFOLD: dissolution trigger = Step 2 brief enumerates variant set against lower.rs Diagnostic emission sites + Q6.5 anti-bridge preserved + PR #3077 §12 Q7 ratification path. - DiagnosticAnchor 🟢 TERMINAL: closed-axis covering all lowering-stage anchor kinds; no further dissolution. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * docs(r3): cursor PR #3077 INLINE BLOCKING line:161 — DiagnosticSource Practice 4 classification Cursor inline finding adds DiagnosticSource to Practice 4 classification scope. Earlier commit aba79a142 classified SurfaceFormRef + IdentifierRef + LowerDiagnostic + DiagnosticAnchor but missed DiagnosticSource. Fix: DiagnosticSource 🟢 TERMINAL at pipeline-stage discrimination scope. Closed-axis sum (Parse | Lower | Infer | Emit); adding new pipeline stage requires explicit substrate- extension audit per Practice 4 + stop-signal discipline (same shape as PB-5 §3.2 TypeConnective stop-signal). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * docs(r3): cursor PR #3126 INLINE BLOCKING line:151 — §11 SurfaceItem::Let + SurfaceLiteral span correction Cursor INLINE BLOCKING line:151: §11 claimed "every Surface variant carries SourceSpan" but live parse_surface.dag has: - SurfaceItem::Let { name, type_ann, expr } — no direct span - SurfaceLiteral = Int(String) | Bool(Bool) | String(String) — plain-tuple variants with no direct span Source-span provenance for these cases is via enclosing carrier: SurfaceLiteral wraps within `Literal { value, span }` at parse_surface.dag:150. Let-item inherits container span. INVARIANTS P2/P3 source provenance is structurally guaranteed via direct-OR-enclosing carrier, but my "every variant" overstatement obscured this. Fix: §11 corrected to "most Surface variants carry SourceSpan directly" + explicit Let + SurfaceLiteral exceptions noted + Step 2 PR scope audits whether exceptions are structural-honest (enclosing-carrier-provides-span) OR require substrate extension. Same recurring overstatement class as earlier "every SurfaceItem maps 1:1 to Declaration" (commit 61e2b67cd) — need to grep live substrate variant fields BEFORE claiming uniform shape. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * WIP: gunbc Director * docs(r3): cursor PR #3126 INLINE BLOCKING line:32 — GrammarSpec is concept, not carrier Earlier draft (now-merged PR #3126) framed `GrammarSpec` as a second declared `.dag` input type alongside `List<Token>`. Verified via grep that no `type GrammarSpec` exists anywhere under src/v3/ or dsl/ — the repo carries only `parse_tables.dag`'s 6 SG-2c table-families. Per cursor 2026-05-14T23:30:04Z inline finding, this violates INVARIANTS P2 (the Step-2 signature names a carrier the substrate doesn't declare). Reframed §3 (and downstream mentions in §3.2, §3 preamble line:33, §4.2 codex-correction recap line:165, §5.1 line:181, §12 Q6 line:344) so that: - Parse has ONE input at the API boundary: `List<Token>`. - "GrammarSpec" is a concept-level grouping for the 6 compile-time table-families in `parse_tables.dag`, not a substrate carrier and not a runtime parameter. - Step-2 signature stays `fn parse(tokens: List<Token>) -> Result<SurfaceModule, ParseDiagnostic>` per cfe842b2d (already applied in #3126); these edits remove the lingering "two input types" framing that contradicted that signature. Per Decision 3.B (b) compile-time parser tables: substrate authority is parse_tables.dag (6 table-families) consumed via direct table lookups inside the parser body — no runtime grammar value, no `GrammarSpec` carrier needed. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * docs(r3): codex PR #3138 BLOCKING — §4.3 + §16 internal contradictions resolved Codex review id 12391 on sha cd6e8d15 flagged two live statements of the already-rejected typed-state-with-coupled-diagnostics model still sitting inside the parse L2.5, contradicting the corrected Result-sum framing in §4.2 and §6 Step 2: 1. §4.3 still proposed a `SurfaceModule { items, diagnostics }` extension modeled on PB-4/PB-5 patterns. Reframed: §4.3 now states explicitly that parse-stage uses Result-sum (no diagnostics field on SurfaceModule), restates the cross-stage discriminator (Result-sum for fail-fast output domains: parse + emit; typed-state for structural output domains: lower + infer), and cites `parse_generated.rs:138` as the live shape. 2. §16 "Memory disciplines applied" bullet read "feedback_state_space_vs_behavioral_invariants (typed-state SurfaceModule at output)". Rewritten to "parse output is `Result<SurfaceModule, ParseDiagnostic>` — the type rules out partial-parse states by construction; SurfaceModule itself carries no diagnostic field per §4.3". Per `feedback_discipline_change_audit_all_contract_mentions`: when a contract changes (here: SurfaceModule extension dropped in favor of Result-sum), all §-internal restatements must be swept in the same diff or they leak through as authoritative parallel claims. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * docs(r3): codex PR #3127 BLOCKING — drop TokenizedSource extension + cite concrete P5 receipts Codex review id 12370 on sha d15e1f29 raised two load-bearing planning-shape findings on the tokenize L2.5. Addressed in this fix-forward branch (PR #3138) since PR #3127 is still open but accumulating cycles. Finding 1 — parallel boundary carriers (INVARIANTS P2 / Modeling Practices 3+5): §4.3 + §9 Step 2 + §12 Q6 named `TokenizedSource { tokens, diagnostics }` as the output, while §2/§7.2/§7.3 named `List<Token>`. Same misclassification I just removed from the parse L2.5 in PR #3138 §4.3: tokenize sits in the fail-fast output domain alongside PB-3 parse + PB-6 emit (a partial token list with a corrupt token in the middle is not a valid downstream input for parse), so the failure couples via `Result`, not into the structural carrier. Resolution: - §4.3 rewritten to ratify `Result<List<Token>, TokenizeDiagnostic>` — the live `tokenize_generated.rs:96` shape — with no `TokenizedSource` extension. - §9 Step 2 row signature updated to match; explicit "single canonical boundary carrier: List<Token> on the Ok branch" framing. - §12 Q6 resolved REJECTED in-doc (no operator ratification needed; disposition follows from the cross-stage discriminator that's also load-bearing in PR #3138 parse L2.5). - §16 memory-disciplines bullets rewritten parallel to PR #3138 parse §16: Result-sum, no diagnostics field on `List<Token>`. - §14 "Surfaces awaiting" trimmed Q6 from the operator-ratification list. Finding 2 — soft deferral of `regen_tokenize` retirement (INVARIANTS P5): deferral previously named "PB-Bootstrap-Process lane scope" without a concrete ROADMAP.md row. Updated §9 Step 2 + Step 4 rows to cite the named receipts: - `docs/design-pure-bootstrap-zero.md:116` (PB-Bootstrap-Process lane: author bootstrap.dag + generated trampoline; sized M). - `docs/design-pure-bootstrap-zero.md:118-123` (N=0 runtime verification gates). - ROADMAP.md:467 (Character-level under-consumption in tokenize + syntax authorities — phase-2 char-class retype owns the codegen-driver path). - ROADMAP.md:416 (Class 5 Gap 3 — top-level `ValueBody` boundary; gating substrate-capability for the phase-2 retype). - ROADMAP.md:53 (T-PB-A — non-test census → 0 floor). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * docs(r3): cursor PR #3126 BLOCKING line:119 — §6/§7.2/§15 Q7 sequencing resolved by PR #3077 merge Cursor inline BLOCKING at docs/design-parse-stage-l25-model.md:119 (sha at merge time of PR #3126) flagged a real internal contradiction: - §6 (lines 191, 207, 308) claimed "Step 2 (pipeline-slot declaration) is unblocked" - §7.2 (line 227) claimed "PR #3077 §12 Q7 must ratify before any Step 2 worker brief authoring" A worker reading the doc could land Step 2 (pipeline boundary) before the diagnostic carrier's P2/P3 failure shape was fixed. Resolution: PR #3077 (PB-4 lower L2.5) merged at 2026-05-15T00:21:19Z, carrying the §12 Q7 ratification of the Decision 2.B per-stage diagnostic extension path. The gate IS now satisfied at HEAD, so the resolution is fact-update (annotate Q7 as DONE with the merge timestamp) rather than retracting either §6 or §7.2. Edits: - §15 step 4: annotated "DONE 2026-05-15T00:21:19Z when PR #3077 merged" and added the explicit "Step 2 is now genuinely unblocked, not just procedurally next" framing so workers reading the sequence don't bypass the gate. - §7.2 line 227: rewritten from "Q7 must ratify before Step 2 brief authoring" (future tense, the contradiction surface) to "Gate satisfied 2026-05-15T00:21:19Z when PR #3077 merged; Step 2 worker brief authoring is unblocked at HEAD per §15 step 4." Cites the cursor finding as the resolution path. §6 unblocking statements stay as-is — they were correct at HEAD; the contradiction lived in §7.2's pre-merge framing. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * docs(r3): codex PR #3126 BLOCKING (sha 16d21f4a) — Q7 cited at every Step 2 unblocking claim Codex BLOCKING finding 2 (sha 16d21f4a, 216s thinking): the Q7 dependency was recorded in §7.2/§15 but not in the other Step-2-unblocking sites at §6 lines 191, 207, 308 — risking a worker reading "Step 2 unblocked" without also reading the Q7 prerequisite. Codex framing: "make Q7 a hard precondition wherever Step 2 is called unblocked, or split Step 2 into pre-Q7 and post-Q7 scopes with separate receipts." Chose the first option since PR #3077 has already merged (2026-05-15T00:21:19Z) and splitting into pre/post-Q7 scopes is no longer load-bearing. Annotated all three §6 sites: - Line 191 (Implication for PB-3 migration): cites gate + merge timestamp + explicit "must NOT be brief-authored before that merge timestamp." - Line 207 (Critical observation): cites the Step 2 gate as PR #3077 §12 Q7 + merge timestamp + P3 failure-shape consequence if violated. - Line 308 (Director-recommend phase list): cites gate + §7.2/§15 step 4 cross-refs + merge timestamp. Codex BLOCKING finding 1 (GrammarSpec carrier non-existence) verified already resolved at HEAD via commit c97dc15ae — every GrammarSpec mention now explicitly marks it as a concept-not-carrier; Step 2 signature is `fn parse(tokens: List<Token>) -> Result<SurfaceModule, ParseDiagnostic>` with no GrammarSpec parameter. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * docs(r3): openai-pro PR #3126 BLOCKING (sha 16d21f4a) — Step 3b/4 atomicity + Q1 ratification-pending status openai-pro REQUEST_CHANGES on PR #3126 sha 16d21f4a flagged three findings. Findings 1 + 2 (signature vs realization mismatch under LAYER MODEL + P2/P3 boundary discipline) were already resolved at HEAD by earlier fix-forward commits — Step 2 signature is now `fn parse(tokens: List<Token>) -> Result<SurfaceModule, ParseDiagnostic>` matching live `parse_generated.rs:138` with no GrammarSpec parameter and no diagnostics-coupled SurfaceModule extension (§4.3 Result-sum disposition). Finding 6 (TRACKED vs UNTRACKED DEBT — Step 3b/4 same-PR vs two-PR): §9 had both a "Step 3b/4 COMBINED" row (line 250) and a leftover separate "Step 4: Parity test" row (line 251) — internally contradictory. §15 also still sequenced Steps 3b + 4 as four separate authoring/dispatch/ratify beats (steps 12-17), contradicting §12 Q5's "same PR" decision and the explicit "Update to §15" note at §12 line 325. Resolution: collapsed §9 to one COMBINED row absorbing the parity-TestClaim mechanics + P5 dissolution receipt from the deleted Step 4 row; collapsed §15 steps 12-17 into single COMBINED authoring + dispatch + ratify (steps 12-14). Added explicit `feedback_paper_shrink_variants` reasoning in both sections. Finding 2.5 (PM intent — substrate-capability bundled vs separate): §12 Q1 line 288 said "Director-recommend: (b) bundled" while §13 line 340 listed substrate-capability as a non-goal of PB-3 and §15 step 11 had "WAIT for substrate-capability landing" — three sections, two different execution paths. Resolution: annotated Q1 as "PENDING operator/PM ratification" with explicit default-execution clause: until operator ratifies, the doc treats substrate-capability as path (a) separate lane (matching §13 + §15 + §9 row). If/when ratified to (b), §13 drops the non-goal and §15 step 11 collapses into the COMBINED Step 3b/4 brief. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * docs(r3): codex PR #3126 BLOCKING (sha 5619afac) — parse_tables.dag as single enumerated authority Codex caught me copying the prose summary at parse_tables.dag:23-29 (which enumerates only SG-2c-numbered families) instead of grepping the live `^type [A-Z]` declarations. Result: SoftKeywordIdentRow (line 334) was missing from §3.2 / §5.1 / §6 / §12 because it lacks an SG-2c-N number in the prose summary. Per `feedback_parallel_representation_debt`: structural fix is to stop hand-enumerating in the doc — cite parse_tables.dag itself as the single enumerated authority and use `type`-declaration line-anchors for the worked example, not a hand-maintained count. Edits: - §3.2 §"Live substrate authority": replaced the SG-2c-numbered bullet list with `type`-declaration line-anchor enumeration including SoftKeywordIdentRow at parse_tables.dag:334 + the supporting enum BinaryOpLevel at line 133. Added codex-finding callout explaining the miss + the discipline shift. - §3 preamble line:33, §3.2 line:45 callout, §3.2 line:57 framing, §3.2 §"Substrate authority" line:71, §5.1 line:171-180, §12 Q2 line:298, §12 Q6 line:334: all hardcoded "6 table-families" counts dropped; doc now points readers to §3.2 enumeration / `parse_tables.dag` directly. - §5.1 sub-enumeration list (the parallel 6-item list at lines 173-178) deleted; replaced with redirect to §3.2 + restated 3a-vs-3b/4 scope split. Code-level check before commit: `grep -nE '^type [A-Z]' src/v3/compiler/parse_tables.dag` returns 7 types: BinaryOpLevel (133), BinaryOpRow (167), TopLevelItemKwRow (289), SoftKeywordIdentRow (334), BracketRow (385), PrimaryPrefixRow (449), PrimaryAtomRow (486). Doc enumeration matches. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * docs(r3): codex PR #3138 BLOCKING (sha f08b9525) — bind TokenizeDiagnostic to live CharClass authority Codex Finding 1 (sha f08b9525, 216s thinking): the §4.2 TokenizeDiagnostic draft and the §5.1/§5.2 headings used `ScannerCharClass` / `ScannerClassRef` — names that exist only as the *generated Rust enum spelling*, not as a declared .dag substrate type. Verified via grep: grep -rn '^type CharClass\|^type ScannerC' dsl/ src/v3/ returns ONE authority: `dsl/std/unicode.dag:62` type CharClass = Whitespace | Digit | IdentStart | IdentContinue consumed at `src/v3/compiler/tokenize.dag:103` data ascii_scan_order: List<CharClass> = [Whitespace, Digit, IdentStart, IdentContinue] There is no `ScannerCharClass` declaration anywhere — that name was copied from generated Rust without grep-verification, the same failure mode as `feedback_grep_substrate_before_naming_ratification` (carrier-name collision discipline). Resolution: - §4.2 TokenizeDiagnostic carrier: `expected_class: ScannerClassRef` → `expected_class: CharClass`, dropped the `type ScannerClassRef = ScannerCharClass` alias entirely; added a codex-finding callout citing the substrate authority + naming the failure mode. - §5.1 heading "Byte → ScannerCharClass dispatch" → "Byte → CharClass dispatch"; bullets unchanged; added line-anchor cites for the substrate authority + explicit "NOT ScannerCharClass" disclaimer. - §5.2 heading "ScannerCharClass → token-recognition state machine" → "CharClass → token-recognition state machine". Finding 2 (TokenizedSource not reconciled with parse input contract): no new fix required — already resolved by commit 6adb99227 (TokenizedSource extension dropped entirely; tokenize uses Result<List<Token>, TokenizeDiagnostic>; List<Token> is the single canonical boundary carrier consumed by parse). Codex was reviewing sha f08b9525, which predated the TokenizedSource drop. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * docs(r3): cursor PR #3138 INLINE BLOCKING line:188 — clarify §7.3 chain is Ok-branch propagation Cursor INLINE at sha f08b9525 worried that §7.3's cross-stage chain "tokenize → List<Token> → parse → ..." was inconsistent with §4.3's TokenizedSource carrier (diagnostics not flowing forward). At HEAD the TokenizedSource extension is dropped (commit 6adb99227); tokenize uses Result<List<Token>, TokenizeDiagnostic>, so List<Token> IS the canonical Ok-branch payload that flows forward and Err branches terminate the pipeline fail-fast. To make this explicit at §7.3 (instead of leaving readers to infer it from §4.3), annotated the chain with: - "Ok-branch propagation; Err branches are stage-terminal fail-fast per §4.3 Result-sum discriminator" framing prefix. - Per-stage Result/typed-state annotations: tokenize/parse show Result<Ok, Err>; lower/infer show typed-state structural-output; emit shows Result<EmittedArtifact, EmissionDiagnostic>. - Explicit "on any stage's Err branch the pipeline aborts at that stage (no partial-output propagation across boundaries)" trailer. This makes the chain self-consistent vis-a-vis §4.3 without requiring the reader to walk back-and-forth, and prevents future readers from re-introducing a TokenizedSource-shaped extension to "make diagnostics flow forward" — they already do, just via the Err branch terminating the pipeline. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * docs(r3): openai-pro PR #3127 BLOCKING (sha d15e1f29) — character-level scaffold dissolution trigger openai-pro REQUEST_CHANGES on sha d15e1f29: §1 line:26 character-level under-consumption scaffold named the problem but lacked a checkable dissolution trigger. SG-1a scaffold above had the right shape — "once those bodies lower structurally under compile_to_dag, delete the raw-text extractor + derive directly from lowered Dag in same PR." Character-level scaffold just said "PB-2 Step 4 carries this scope" — a lane assignment, not a trigger. Resolution: rewrote §1 item 2 with the same SG-1a-shape trigger structure: - Substrate-consumption condition (a): scanner classes / string escape / local punctuation retype to `dsl/std/unicode.dag` `CharClass` / `char_in_class` (concrete field retypes named: `StringEscapeSpec.suffix: Char`, `LocalPunctSpec.pattern: List<Char>`, `string_literal_delimiter: Char`). - Codegen-driver condition (b): `tokenize_generated.rs` no longer emits hidden `byte.is_ascii_*` predicates because the driver reads class facts structurally from lowered `tokenize.dag`. - Same-PR dissolution: delete the parallel character-predicate scaffold in the same PR that flips substrate consumption — no Rust-and-`.dag` coexistence per `feedback_paper_shrink_variants`. - Cross-ref to §9 Step 4 gating prereqs: ROADMAP.md:467 + ROADMAP.md:416 Class 5 Gap 3 + std.unicode bootstrap/load-set decision (already cited in §9 from earlier commit 6adb99227). Per openai-pro's framing: "small fix — mirror the SG-1a scaffold wording by naming the exact substrate-consumption condition and same-PR deletion receipt for the hidden Rust character predicates." Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * WIP: gunbc Director * docs(r3): cursor PR #3127 APPROVE_WITH_COMMENTS — §14 + §15 Q6-already-rejected sweep Cursor review id 12405 (APPROVE_WITH_COMMENTS) caught the same `feedback_discipline_change_audit_all_contract_mentions` failure mode recurring: §12 Q6 was resolved REJECTED in commit 6adb99227, and §14 "Surfaces awaiting" + §12 Q6 heading + §9 Step 2 row were updated, but two §-internal contract restatements were missed: - §14 acceptance criterion 11: "Operator/PM ratification on §12 Q1-Q6" - §15 step 1: "Operator / PM-delegate ratifies §12 Q1-Q6" Both contradicted §12 Q6 + §14 "Surfaces awaiting" (which already said "Q1-Q5 only"). A worker reading §14/§15 could schedule sign-offs on Q6 after it was already resolved-rejected elsewhere. Resolution: both sites now say "Q1–Q5" with the explicit Q6-rejected crossref + "see §14/§15 for same scoping" pointer at the §14 criterion so the three sections agree internally. Cursor verdict was APPROVE_WITH_COMMENTS (substantive APPROVE — "fix the checklist/sequence so every section agrees Q6 is closed"); the exploratory volatile-line-anchor note is harmless and out-of-scope for this PR. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * docs(r3): codex PR #3138 BLOCKING (sha 887c69671) — 3 findings swept across 3 L2.5 docs Codex review id (sha 887c69671, 333s thinking) flagged three findings, all `feedback_discipline_change_audit_all_contract_mentions` recurrences where partial sweeps left §-internal contradictions. Finding 1 — infer doc cross-stage trigger leak: §4.2 InferDiagnostic dissolution trigger said "when Step 2 worker brief enumerates the full variant set against `parse_generated.rs` Diagnostic::ParseError, lower.rs Diagnostic construction sites, and infer.rs Dag::mark_unresolved emission sites." That cross-stage trigger surface is wrong for the infer-specific scaffold. Narrowed to infer-only: "against `src/v3/compiler/src/infer.rs` Diagnostic construction sites + `Dag::mark_unresolved` emission sites (infer-stage only)." Parse and lower have their own per-stage carriers + own Q7 mapping; this doc no longer reaches into their dissolution-trigger surface. Finding 2 — parse + tokenize coproduct receipts: `ParseDiagnosticKind` (parse §4.2) and `TokenizeDiagnostic` (tokenize §4.2) sums were declared without the 🟡 SCAFFOLD / 🟢 TERMINAL classification + dissolution trigger that the infer doc carries (per modeling-discipline Practice 4 + `feedback_coproduct_dissolution`). Added matching scaffold receipts to both: 🟡 SCAFFOLD at PROPOSED stage with stage-local dissolution trigger (Step 2 brief enumerates against parse_generated.rs / tokenize_generated.rs Diagnostic::* construction sites — stage-only, not cross-stage); promote to 🟢 TERMINAL when full variant set lands. Both also carry the anti-bridge note per Q6.5. Finding 3 — tokenize Q7 reconciliation: The parse doc has the "Q7 DONE 2026-05-15T00:21:19Z" annotation at §15 step 4 (commit f85fa1f6b) but the tokenize doc still framed Q7 as a pending lane dependency at §4.2 line:113 ("Lane dependency"), §15 step 3, and §14 "Surfaces awaiting". Annotated all three: - §4.2 "Lane dependency": Q7 DONE timestamp + "TokenizeDiagnostic per-stage variant authoring is the remaining lane work." - §15 step 3: full DONE annotation matching parse doc §15 step 4 shape + cross-ref to the parse doc. - §14 "Surfaces awaiting": strikethrough + DONE annotation. PR #3127 also carries the tokenize doc; same edits will port there in a companion commit. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * docs(r3): cursor PR #3138 INLINE BLOCKING line:372 — §16 Surfaces awaiting Q7 contradiction Cursor inline at sha 887c69671 caught the symmetric finding to the codex 5-finding BLOCKING #3: parse-doc §15 step 4 already annotated Q7 as DONE (commit f85fa1f6b) but parse-doc §16 "Surfaces awaiting" still listed Q7 as pending. Same `feedback_discipline_change_audit_all_contract_mentions` sweep failure — the tokenize doc had three sites carrying the pending framing (commit e9739ea4f fixed those) but the parse doc's §16 site was missed in the original Q7-DONE sweep. Resolution: §16 bullet now strikes through + "DONE 2026-05-15T00:21:19Z (PR #3077 merged carrying Q7 ratification; see §15 step 4)" — same shape as the tokenize doc's §14 "Surfaces awaiting" Q7-DONE annotation landed in e9739ea4f. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * docs(r3): codex PR #3127 BLOCKING (sha 8e682eef) — §3.1 source identity + §4.2 live-vs-proposed clarity PR #3127 was merged at 02:04:22Z but codex's later review on sha 8e682eef caught two findings that still live in main. Both addressed in this PR (PR #3140) since the tokenize doc lives on main and this is the open post-merge cleanup branch. Finding 1 — §3.1 source-identity drop: Earlier draft framed tokenize input as bare `String → List<Token>`. That contradicts live `tokenize_generated.rs:96`: pub fn tokenize(source: &str, file: &str) -> Result<Vec<Token>, Diagnostic> The `file` parameter is load-bearing because `SourceSpan` requires a file/source-id field for byte ranges to be attributable; without it the Token + Diagnostic span fields would have to fabricate source-id at the pipeline boundary (P3 fail-closed violation). §3.1 now ratifies the live two-input shape: - `source: String` — UTF-8 source text (primitive). - `file: SourceFileId` — source-identity carrier; Step 2 brief ratifies the appropriate `.dag` shape (NonEmptyStr newtype or richer sum if multiple source-class kinds). Finding 2 — §4.2 live-vs-proposed blur: Prior framing said "TokenizeDiagnostic (substrate extension per Decision 2.B)" without making clear that this is a PROPOSED per-stage carrier, not the live one. The live carrier at `diagnostics.dag:150` is generic `Diagnostic { kind: AnyDiagnosticKind, ... }` with kind sum at `:139-142` discriminating CompilerKind vs LensInstanceKind; tokenize emits today via `Diagnostic::TokenizerError`-shaped sites carrying `kind: CompilerKind(...)`. §4.2 heading now reads "PROPOSED — NOT yet live" + a codex-finding callout explicitly distinguishing the live carrier from the proposed per-stage refinement + Q7 status DONE. Both fixes preserve the e9739ea4f 🟡 SCAFFOLD coproduct receipt that was already addressing codex sha 887c69671 Finding 2. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * docs(r3): cursor PR #3127 INLINE BLOCKING line:121 — §4.3 + §9 Step 2 signature sweep Cursor inline at sha 8e682eef line:121 (the §4.3 Step 2 signature site) caught the same source-identity drop my §3.1 fix already addressed at the input-type framing — but two companion sites still had the single-input signature: - §4.3 line:151 Step 2 signature recap - §9 Step 2 row (4-step migration table) Both now read: fn tokenize(source: String, file: SourceFileId) -> Result<List<Token>, TokenizeDiagnostic> matching the §3.1 source-identity discipline + live `tokenize_generated.rs:96` `pub fn tokenize(source: &str, file: &str)` shape. Same `feedback_discipline_change_audit_all_contract_mentions` recurrence — my Finding 1 fix at §3.1 (commit 18af49fad) didn't sweep the §4.3 + §9 contract-signature restatements. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * docs(r3): cursor PR #3127 INLINE BLOCKING line:166 — §6 row TokenizeDiagnostic LIVE/PROPOSED clarity Cursor inline caught ambiguity in the §6 prereq-table row for "TokenizeDiagnostic substrate extension." Old wording in column 4 read "Carrier LIVE; per-stage variant authoring NEW" which could be parsed as "TokenizeDiagnostic carrier itself is LIVE" — but no `type TokenizeDiagnostic` exists in `dsl/std/` or `src/v3/std/`. Only the generic `type Diagnostic` at `diagnostics.dag:150` is live. Cursor's secondary claim that "line 150 is EmissionDiagnostic receipt prose" is INCORRECT — verified via grep + read: `diagnostics.dag:150` is the `type Diagnostic { kind: AnyDiagnosticKind, ... }` declaration header. `type EmissionDiagnostic` lives separately at `diagnostics.dag:201`. The §6 row's citation of `:150` for the underlying Diagnostic carrier is correct. But the ambiguity-in-wording finding stands. Reframed the row: - Column 1: explicitly "PROPOSED — no `type TokenizeDiagnostic` exists yet" - Column 2: clarifies the LIVE underlying carrier is `type Diagnostic` with `kind: AnyDiagnosticKind` sum at `:139-142`; cites Q7 ratification done timestamp. - Column 4: explicit "Underlying Diagnostic carrier LIVE at HEAD; per-stage TokenizeDiagnostic variant authoring is NEW work, NOT live substrate" with cursor-finding callout. Consistent with §4.2's "PROPOSED — NOT yet live" framing from commit 18af49fad. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * docs(r3): cursor PR #3141 INLINE BLOCKING line:68 — §2 structural-signature sweep Cursor inline caught §2 still framing tokenize structural signature as `String → List<Token>` — single bare-string input, no source-identity, no Result-sum failure shape — while §3.1 + §4.3 + §9 Step 2 row all ratify the live two-input + fail-fast Result-sum shape. Same `feedback_discipline_change_audit_all_contract_mentions` recurrence that's been compounding across this fix-forward sequence: each finding fix needs a doc-wide signature-restatement sweep, not just the §-local sentence. Resolution: §2 structural-shape sentence now reads `(String, SourceFileId) → Result<List<Token>, TokenizeDiagnostic>` matching §3.1 (source-identity), §4.3 (Result-sum cross-stage discriminator), §9 Step 2 row, and live `tokenize_generated.rs:96` `pub fn tokenize(source: &str, file: &str) -> Result<Vec<Token>, Diagnostic>`. Cross-refs added to §3.1 + §4.3 to make the discipline visible at the high-level framing. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * docs(r3): cursor PR #3141 INLINE BLOCKING line:73 — replace invented SourceFileId with live FilePath Cursor caught me inventing `SourceFileId` as the Step 2 boundary type without a live `.dag` declaration. Verified via grep: grep -rn '^type SourceFileId' dsl/ src/v3/ returns empty. Same `feedback_grep_substrate_before_naming_ratification` family error as the earlier `ScannerCharClass` miss — naming a substrate carrier without grep-verification. Live carrier already exists at `dsl/std/types.dag:276`: type FilePath = String where non_empty referenced by `type SourceSpan { file: FilePath, ... }` at `dsl/std/types.dag:293`. So source identity flows through every Token + Diagnostic span field via the live `FilePath` carrier — no new carrier authoring needed at Step 2. Edits: - §2 structural-signature: `(String, SourceFileId)` → `(String, FilePath)` - §3.1 source-identity bullet: replaces fictional SourceFileId with the live `FilePath` declaration cite (dsl/std/types.dag:276), points out that `SourceSpan.file` already references this same carrier, and adds a cursor-finding callout naming the failure mode. - §4.3 + §9 Step 2 signature restatements: `file: SourceFileId` → `file: FilePath`. Single substrate authority (INVARIANTS P1/P2) restored: FilePath is the one carrier for source identity across SourceSpan + tokenize input + Token construction. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Summary
Post-merge fix-forward addressing residual issues from merged PR #3077 / #3085 / #3126 at 2026-05-15T00:21Z. Now covers 4 post-merge findings across 2 docs (PB-4 lower + PB-3 parse L2.5s).
Issues addressed
PB-4 lower §16 (per cursor APPROVE_WITH_COMMENTS PR #3077)
§16 "Memory disciplines applied" bullet said "diagnostics coupled INTO PreInferDag via biconditional" — but §4.3 (per openai-pro DiagnosticAnchor fix b812db9) constrains biconditional to PortAnchor-only. Other anchor kinds (DeclarationAnchor / RecordFieldAnchor / SurfaceFormAnchor) couple without port-state coupling.
Fix in commit f08b952: §16 bullet honors §4.3 anchor-typed framing.
PB-3 parse §9 Step 2 (per claude APPROVE PR #3126 exploratory obs)
§9 Step 2 row described diagnostics as "coupled INTO SurfaceModule" as if live — §4.3 correctly marks it PROPOSED. Same
feedback_discipline_change_audit_all_contract_mentionspattern.Fix in commit f08b952: §9 Step 2 row clarified — "PROPOSED extension per §4.3".
PB-3 parse §3.2 GrammarSpec parallel-authority (per codex REQUEST_CHANGES PR #3126)
§3.2 says GrammarSpec is compile-time-only NOT runtime-interpreted (per Decision 3.B (b)). But proposed stage contract still took
grammar: GrammarSpecas runtime input. Two authorities (compiled tables + runtime spec value). P2 violation.Fix in commit cfe842b: §4.3 signature
fn parse(tokens) -> Result<SurfaceModule, ParseDiagnostic>— NO runtime GrammarSpec input.PB-3 parse §4.3 fail-closed weakening (per codex REQUEST_CHANGES PR #3126)
Live parser at
parse_generated.rs:138returnsResult<SurfaceModule, Diagnostic>(fail-closed). Earlier doc proposed embedded-diagnostics-in-SurfaceModule shape — would let partial-parse states be constructible. P3 + Practices 1/2 violation.Fix in commit cfe842b: signature preserves Result-sum. Cross-stage discriminator named: Result-sum (parse + emit) for fail-fast output domain; typed-state-with-coupled-diagnostics (lower + infer) for structural-output-with-partial-failure domain.
Pattern
All 4 findings cluster around
feedback_discipline_change_audit_all_contract_mentions— when substantive review-cycle fixes change a discipline framing in one section, audit ALL sections (framing + contract + handoff + cross-references) before merge. This session has surfaced this pattern 5+ times now.Test plan
🤖 Generated with Claude Code